Deprecation warning when using has_many :through :uniq in Rails 4

23,052

Solution 1

The uniq option needs to be moved into a scope block. Note that the scope block needs to be the second parameter to has_many (i.e. you can't leave it at the end of the line, it needs to be moved before the :through => :donations part):

has_many :donors, -> { uniq }, :through => :donations

It may look odd, but it makes a little more sense if you consider the case where you have multiple parameters. For example, this:

has_many :donors, :through => :donations, :uniq => true, :order => "name", :conditions => "age < 30"

becomes:

has_many :donors, -> { where("age < 30").order("name").uniq }, :through => :donations

Solution 2

In addition to Dylans answer, if you happen to be extending the association with a module, make sure that you chain it in the scope block (as opposed to specifying it separately), like so:

has_many :donors,
  -> { extending(DonorExtensions).order(:name).uniq },
  through: :donations

Maybe its just me but it seems very unintuitive to use a scope block to extend an association proxy.

Share:
23,052
Ryenski
Author by

Ryenski

Ruby on Rails developer specializing in full-stack SaaS app development, MVP (minimum viable product) deployment, and custom software integration.

Updated on April 04, 2020

Comments

  • Ryenski
    Ryenski about 4 years

    Rails 4 has introduced a deprecation warning when using :uniq => true with has_many :through. For example:

    has_many :donors, :through => :donations, :uniq => true
    

    Yields the following warning:

    DEPRECATION WARNING: The following options in your Goal.has_many :donors declaration are deprecated: :uniq. Please use a scope block instead. For example, the following:
    
        has_many :spam_comments, conditions: { spam: true }, class_name: 'Comment'
    
    should be rewritten as the following:
    
        has_many :spam_comments, -> { where spam: true }, class_name: 'Comment'
    

    What is the correct way to rewrite the above has_many declaration?

  • Ryenski
    Ryenski almost 11 years
    Thanks, this works great! Where did you find this? I haven't been able to find it in the documentation anywhere.
  • Dylan Markow
    Dylan Markow almost 11 years
    I actually saw it in the Upgrading to Rails 4 book (it's in progress): upgradingtorails4.com -- haven't been able to find it anywhere else.
  • Ivar
    Ivar over 9 years
    @DylanMarkow the link for Upgrading to Rails 4 is defunct. The book has now been released under a CC license at github.com/alindeman/upgradingtorails4
  • Nic Nilov
    Nic Nilov over 6 years
    With Rails 5 use distinct instead of uniq. See this answer for more details.