Rails: Can't have a scope called `public` anymore with Rails 4.1?

Created on 9 May 2014  路  3Comments  路  Source: rails/rails

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>

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 called public to the model class, which overrides the one on Module the controls methods visibility.

All 3 comments

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.

Was this page helpful?
0 / 5 - 0 ratings