On Rails 4.1, the following model
class Product < ActiveRecord::Base
scope :public, where(true)
end
gives me this error:
ArgumentError: You tried to define a scope named "public" on the model "Product", but Active Record already defined a class method with the same name.
from /usr/local/stow/ruby-2.1.1-gh-2014.3.18/lib/ruby/gems/2.1.0/gems/activerecord-4.1.1/lib/active_record/scoping/named.rb:143:in `scope'
from /tmp/scope/app/models/product.rb:2:in `<class:Product>'
from /tmp/scope/app/models/product.rb:1:in `<top (required)>'
There's no error on Rails 4.0.5. Is this an intended breaking change for 4.1?
I see that that Module.public exists http://ruby-doc.org/core-2.1.1/Module.html#method-i-public
irb(main):001:0> Product.method(:public)
=> #<Method: Class(Module)#public>
Yes, it is intentional. See #14582 and the recent 7e8e91c for more details.
@gsamokovarov Thanks!
Yes, this is a new thing on Rails 4.1. These scopes with "reserved" names has always been problematic and a cause for many subtle bugs, so we decided to fail loudly instead.
In this case, the conflict is with the Module.public method as you suggested. By defining a scope called public
, it will add a class method called public
to the model class, which overrides the one on Module
the controls methods visibility.
Most helpful comment
Yes, this is a new thing on Rails 4.1. These scopes with "reserved" names has always been problematic and a cause for many subtle bugs, so we decided to fail loudly instead.
In this case, the conflict is with the Module.public method as you suggested. By defining a scope called
public
, it will add a class method calledpublic
to the model class, which overrides the one onModule
the controls methods visibility.