I spend few hours trying to find solution of my problem, but lost any hope to understood what i am done wrong.
Rails 4.2.6
my model:
app/models/component.rb
class Component < ActiveRecord::Base
validates :name, presence: true,
uniqueness: true,
forbid_changing: true #TODO [VS] Fix custom validator autoload
validates :label, presence: true,
uniqueness: true
end
my validator:
class ForbidChangingValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if record.send "#{attribute}_changed?".to_sym
record.errors[attribute] << options[:message] || t(:changing_forbidden)
end
end
end
when try reload the page i got error:
Unknown validator: 'ForbidChangingValidator'
ArgumentError - Unknown validator: 'ForbidChangingValidator':
activemodel (4.2.6) lib/active_model/validations/validates.rb:120:in `rescue in block in validates'
activemodel (4.2.6) lib/active_model/validations/validates.rb:117:in `block in validates'
activemodel (4.2.6) lib/active_model/validations/validates.rb:113:in `validates'
app/models/component.rb:6:in `<class:Component>'
app/models/component.rb:1:in `<top (required)>'
activesupport (4.2.6) lib/active_support/dependencies.rb:457:in `block in load_file'
activesupport (4.2.6) lib/active_support/dependencies.rb:647:in `new_constants_in'
activesupport (4.2.6) lib/active_support/dependencies.rb:456:in `load_file'
activesupport (4.2.6) lib/active_support/dependencies.rb:354:in `require_or_load'
activesupport (4.2.6) lib/active_support/dependencies.rb:494:in `load_missing_constant'
activesupport (4.2.6) lib/active_support/dependencies.rb:184:in `const_missing'
activesupport (4.2.6) lib/active_support/inflector/methods.rb:261:in `block in constantize'
activesupport (4.2.6) lib/active_support/inflector/methods.rb:259:in `constantize'
activesupport (4.2.6) lib/active_support/core_ext/string/inflections.rb:66:in `constantize'
repositor (0.6.0) lib/repositor/active_record.rb:6:in `initialize'
but when i am trying to call this validator from console i got:
!! #<ArgumentError: A copy of Component has been removed from the module tree but is still active!>
I found a lot of messages about thig issue, but can't to resolve mine.
Please, help somebody....
I found the issue. It's about naming policy. It strange ways rails try inflect the validator name.
I renamed my validator to ForbidChangesValidator and file also.
Everything goes great.
Thx all for attention.
Custom validations using using ActiveModel::EachValidator need to be declared in the root namespace or "core" autoload paths (however you want to define these directories).
For example:
(YES means will work and NO means won't work)
app/validations => YES since it is a new dir off of app/ it qualifies for root namespace
app/models => YES since it is a core directory
app/models/concerns => YES since it is a core directory
app/models/validations => NO Requires name spacing since it is a child directory off a core one.
Restarting the server fixed the issue for me, since everything else was right in place
Make sure you defined ForbidChangingValidator at app/validators/forbid_changing_validator.rb and add the configuration to:
config/application.rb
# add custom validators path
config.autoload_paths += %W["#{config.root}/app/validators/"]
Related
I am currently trying to implement activity_notification gem. The issue I am having, is the gem is searching for the user_id, but I have implemented friendly_id and the gem is unable to find the user. The parameters show {"target_type"=>"users", "devise_type"=>"users", "user_id"=>"dannytom222"} and then the gem fails with Couldn't find User. I'm using the predefined controller for the gem, and cannot locate the method that is throwing this error.
In my stack trace, it shows
def find_by!(*args) # :nodoc:
find_by(*args) || raise(RecordNotFound.new("Couldn't find #{name}", name))
end
Full trace
activerecord (5.1.5) lib/active_record/core.rb:228:in `find_by!'
activity_notification (1.4.4) lib/activity_notification/controllers/common_controller.rb:28:in `set_target'
activesupport (5.1.5) lib/active_support/callbacks.rb:413:in `block in make_lambda'
activesupport (5.1.5) lib/active_support/callbacks.rb:197:in `block (2 levels) in halting'
actionpack (5.1.5) lib/abstract_controller/callbacks.rb:12:in `block (2 levels) in <module:Callbacks>'
activesupport (5.1.5) lib/active_support/callbacks.rb:198:in `block in halting'
friendly_id for user.rb
extend FriendlyId
friendly_id :username, use: :slugged
migration file for friendly_id slug
class AddSlugToUsers < ActiveRecord::Migration[5.1]
def change
add_column :users, :slug, :string
add_index :users, :slug, unique: true
end
end
How can I get activity_notification to accept the username attribute, in place of the user_id?
UPDATE:
I changed the link_to method to
<%= link_to 'Notifications' user_notifications_path(current_user.id) %> and it works.
You probably have to user user.friendly_id or however, you have declared it to your model instead of user.id. This seems to the issue
I upgraded to Rails 5 and after starting the server the login forms must be loaded. Then this error occurs:
ArgumentError - invalid argument: nil.:
activerecord (5.0.0.1) lib/active_record/relation/spawn_methods.rb:36:in `merge'
activerecord (5.0.0.1) lib/active_record/scoping/default.rb:119:in `block (2 levels) in build_default_scope'
activerecord (5.0.0.1) lib/active_record/scoping/default.rb:117:in `block in build_default_scope'
activerecord (5.0.0.1) lib/active_record/scoping/default.rb:141:in `evaluate_default_scope'
activerecord (5.0.0.1) lib/active_record/scoping/default.rb:116:in `build_default_scope'
activerecord (5.0.0.1) lib/active_record/scoping/named.rb:33:in `default_scoped'
activerecord (5.0.0.1) lib/active_record/scoping/named.rb:28:in `all'
activerecord (5.0.0.1) lib/active_record/scoping.rb:24:in `scope_attributes'
activerecord (5.0.0.1) lib/active_record/scoping.rb:36:in `populate_with_current_scope_attributes'
activerecord (5.0.0.1) lib/active_record/scoping.rb:43:in `initialize_internals_callback'
activerecord (5.0.0.1) lib/active_record/core.rb:317:in `initialize'
activerecord (5.0.0.1) lib/active_record/inheritance.rb:65:in `new'
devise (4.2.0) app/controllers/devise/sessions_controller.rb:9:in `new'
That seems to come from Devise I think?
After searching I found someone with the same error:
Turns it it was a gem which behind the scenes was attempting to do default_scope { nil }, looks like someone implemented protection against that (since it shouldn't really work)
What should I do?
nil is no longer valid as merge parameter, since that method expect a parameter of class ActiveRecord_Relation.
This issue is related to this PR on Rails.
This is the resolution commit on rails.
To avoid this error:
check merge attribute before calling it on a relation, and append it only if it's not null.
or pass always a valid ActiveRecord_Relation to merge, for example <ARModel>.all instead of nil if the actual parameter is nil.
Inside app/models/abc/xyz.rb
module Abc::Xyz
extend ActiveSupport::Concern
end
Inside app/models/abc.rb
class Abc < ActiveRecord::Base
include Abc::Xyz
end
When I try to fetch data from Abc.where(id: id) sometimes it works and sometimes it returns this error(TypeError: wrong argument type Class (expected Module)).
TypeError: wrong argument type Class (expected Module)
app/models/abc.rb:2:in `include'
app/models/abc.rb:2:in `<class:Abc>'
app/models/abc.rb:1:in `<top (required)>'
activesupport (3.2.17) lib/active_support/dependencies.rb:469:in `load'
activesupport (3.2.17) lib/active_support/dependencies.rb:469:in `block in load_file'
activesupport (3.2.17) lib/active_support/dependencies.rb:639:in `new_constants_in'
activesupport (3.2.17) lib/active_support/dependencies.rb:468:in `load_file'
activesupport (3.2.17) lib/active_support/dependencies.rb:353:in `require_or_load'
activesupport (3.2.17) lib/active_support/dependencies.rb:502:in `load_missing_constant'
activesupport (3.2.17) lib/active_support/dependencies.rb:192:in `block in const_missing'
activesupport (3.2.17) lib/active_support/dependencies.rb:190:in `each'
activesupport (3.2.17) lib/active_support/dependencies.rb:190:in `const_missing'
activesupport (3.2.17) lib/active_support/inflector/methods.rb:230:in `block in constantize'
activesupport (3.2.17) lib/active_support/inflector/methods.rb:229:in `each'
activesupport (3.2.17) lib/active_support/inflector/methods.rb:229:in `constantize'
activesupport (3.2.17) lib/active_support/core_ext/string/inflections.rb:54:in `constantize'
I think that you will be better off sticking to the Rails conventions regarding concerns:
Use modules for defining your concerns
Place concerns within app/models/concerns
If you want to namespace your concern as in Abc::Xyz then make sure that you place it in the right path: app/models/concerns/abc/xyz.rb.
Another fine point is that
module Abc::Xyz
assumes that the module Abc has already been defined. If it hasn't it will fail. So maybe you are better using
class Abc
module Xyz
#...
end
end
Note that I used class Abc and not module as your code implied. You can't have both a class and a module with the same name. That could be also why you get the occasional errors. Please see this fine article on Exploring Concerns as well.
Rails try various stuff while (auto)loading constants but you are better off sticking to the conventions. I have seen many cases where the same snippets of code fail in different points in time or in different environments due to the order of definitions/loading/execution of constants.
This isn't the right answer to the OPs issue, but I think it could help people finding this question when searching for the error message.
For me the problem was that I had a helper defined like this:
module Api
class MyControllerHelper
end
end
But Rails expects the helper to be a module not a class, so it should have been like this:
module Api
module MyControllerHelper
end
end
I would like to name my controller ESCsController, ESC being the acronym in question. I found the rails inflection docs which describe a way in which to accomplish this.
http://api.rubyonrails.org/classes/ActiveSupport/Inflector/Inflections.html
Note: Acronyms that are passed to pluralize will no longer be recognized, since the acronym will not occur as a delimited unit in the pluralized result. To work around this, you must specify the pluralized form as an acronym as well:
acronym 'API'
camelize(pluralize('api')) #=> 'Apis'
acronym 'APIs'
camelize(pluralize('api')) #=> 'APIs'
I created my controller and models after adding this to environment.rb
ActiveSupport::Inflector.inflections { |i|
i.acronym 'ESC'
i.acronym 'ESCs'
}
Tested in the console these work perfectly. 'ESC'.pluralize() returns ESCs and 'ESCs'.singularize() returns ESC as expected
Controllers and models were generated through rails generate model ESC and rails generate controller ESCs respectively. This created escs_controller.rb and the model esc.rb as expected.
In my routes.rb I used to have
resources :ESCs, path: '/parts/escs'
which returned this error: 'ESCs' is not a supported controller name. This can lead to potential routing problems. See http://guides.rubyonrails.org/routing.html#specifying-a-controller-to-use
I ended up changing it to:
resources :ESCs, controller: 'escs', path: '/parts/escs'
However, now whenever I try and visit a page I get a circular dependency error:
Circular dependency detected while autoloading constant EscsController
Anyone know what's going on? It looks like whatever is trying to load the controller isn't seeing that it should be ESCsController and not EscsController. I'm new to rails so this could be a simple problem...
I'm using Rails 4.0.2
Here's the relevant part of the full stack trace.
activesupport (4.0.2) lib/active_support/dependencies.rb:461:in `load_missing_constant'
activesupport (4.0.2) lib/active_support/dependencies.rb:184:in `const_missing'
activesupport (4.0.2) lib/active_support/inflector/methods.rb:226:in `const_get'
activesupport (4.0.2) lib/active_support/inflector/methods.rb:226:in `block in constantize'
activesupport (4.0.2) lib/active_support/inflector/methods.rb:224:in `each'
activesupport (4.0.2) lib/active_support/inflector/methods.rb:224:in `inject'
activesupport (4.0.2) lib/active_support/inflector/methods.rb:224:in `constantize'
activesupport (4.0.2) lib/active_support/dependencies.rb:535:in `get'
activesupport (4.0.2) lib/active_support/dependencies.rb:566:in `constantize'
actionpack (4.0.2) lib/action_dispatch/routing/route_set.rb:76:in `controller_reference'
actionpack (4.0.2) lib/action_dispatch/routing/route_set.rb:66:in `controller'
actionpack (4.0.2) lib/action_dispatch/routing/route_set.rb:44:in `call'
actionpack (4.0.2) lib/action_dispatch/journey/router.rb:71:in `block in call'
actionpack (4.0.2) lib/action_dispatch/journey/router.rb:59:in `each'
actionpack (4.0.2) lib/action_dispatch/journey/router.rb:59:in `call'
actionpack (4.0.2) lib/action_dispatch/routing/route_set.rb:680:in `call'
Try moving code that adds the new inflections from environment.rb to config/initializers/inflections.rb then reload the server. Also, you don't need to specify a controller option for your route, just make it resources :escs, path: '/parts/escs' and it shall work fine.
Disclaimer: I'm a Ruby on Rails newbie. Tried Googling and searching StackOverflow without success.
I am creating my first Ruby on Rails app and would like to take advantage of the "thumbs_up" plugin which is similar to vote_fu and acts_as_voteable and works under Rails 3.
https://github.com/brady8/thumbs_up
I have followed the installation instructions on the page above and when I run "gem list" I see the thumbs_up plugin is installed.
I have attempted to add the "acts_as_voteable" mixin to a model which looks like this:
class Foo < ActiveRecord::Base
validates :title, :presence => true
validates :description, :presence => true
acts_as_voteable
end
When I try to browse my app I receive the following error:
undefined local variable or method `acts_as_voteable' for #
The stacktrace does not look very useful to me:
activerecord (3.0.0)
lib/active_record/base.rb:1016:in
method_missing' app/models/foo.rb:7
activesupport (3.0.0)
lib/active_support/dependencies.rb:454:in
load' activesupport (3.0.0)
lib/active_support/dependencies.rb:454:in
load_file' activesupport (3.0.0)
lib/active_support/dependencies.rb:591:in
new_constants_in' activesupport
(3.0.0)
lib/active_support/dependencies.rb:453:in
load_file' activesupport (3.0.0)
lib/active_support/dependencies.rb:340:in
require_or_load' activesupport
(3.0.0)
lib/active_support/dependencies.rb:491:in
load_missing_constant' activesupport
(3.0.0)
lib/active_support/dependencies.rb:183:in
const_missing' activesupport (3.0.0)
lib/active_support/dependencies.rb:181:in
each' activesupport (3.0.0)
lib/active_support/dependencies.rb:181:in
const_missing' activesupport (3.0.0)
lib/active_support/dependencies.rb:503:in
load_missing_constant' activesupport
(3.0.0)
lib/active_support/dependencies.rb:183:in
const_missing' activesupport (3.0.0)
lib/active_support/dependencies.rb:181:in
each' activesupport (3.0.0)
lib/active_support/dependencies.rb:181:in
const_missing'
app/controllers/foos_controller.rb:5:in
`index'
Any ideas? I can't seem to make any progress on resolving this.
Thank you,
-Rob
Try adding an initializer file
# config/initializer/thumbs_up.rb
require 'thumbs_up'
Or you could just require it from your model
# app/models/foo.rb
require 'thumbs_up'