在Rails 4中使用has_many:through:uniq时弃用警告


95

在has_many:through中使用:uniq => true时,Rails 4引入了弃用警告。例如:

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

产生以下警告:

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'

重写上面的has_many声明的正确方法是什么?

Answers:


237

uniq选项需要移到合并范围块中。请注意,作用域块必须是第二个参数has_many(即,您不能将其保留在行尾,需要将其移动到:through => :donations零件的前面):

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

它可能看起来很奇怪,但是如果您考虑具有多个参数的情况,则更有意义。例如,这:

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

变成:

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

谢谢,这很好!您在哪里找到的?我在任何地方的文档中都找不到。
瑞安·克里斯平·塞内斯

6
我实际上是在《升级到Rails 4》一书中看到它的(正在进行中):upgradetorails4.com-在其他任何地方都找不到。
Dylan Markow

1
@DylanMarkow升级到Rails 4的链接已失效。该书现已通过CC许可在github.com/alindeman/upgradingtorails4上发布
Ivar

1
对于Rails 5,请使用distinct代替uniq。有关更多详细信息,请参见此答案
Nic Nilov

5

除了Dylans答案之外,如果您恰巧正在扩展与模块的关联,请确保将其链接在作用域块中(而不是分别指定),如下所示:

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

也许只是我一个人,但是使用范围块来扩展关联代理似乎非常不直观。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.