Предупреждение об устаревании при использовании has_many: through: uniq в Rails 4


95

В Rails 4 появилось предупреждение об устаревании при использовании: uniq => true с has_many: through. Например:

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?

Ответы:


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 - больше нигде не нашел.
Дилан Маркоу

1
@DylanMarkow ссылка для обновления до Rails 4 не работает. Книга выпущена под лицензией CC по адресу github.com/alindeman/upgradingtorails4
Ивар

1
В Rails 5 используйте distinctвместо uniq. См. Этот ответ для получения более подробной информации.
Ник Нилов

5

В дополнение к ответу Диланса, если вы расширяете ассоциацию с модулем, убедитесь, что вы связали его в блоке области (а не указывать его отдельно), например:

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

Может быть, это только я, но мне кажется очень неинтуитивным использовать блок области видимости для расширения прокси-сервера ассоциации.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.