Has_Many: через или: finder_sql - PullRequest
9 голосов
/ 29 марта 2011

Я прибил то, что хочу, но, похоже, не могу понять, что ищут дизайнеры рельсов. По сути, у меня есть (пожалуйста, оставьте в стороне вопросы плюрализации / и т.д.):

Human Отношения (родитель, потомок)

Я пытаюсь получить все потомки для одного родителя и одного родителя для многих потомков (допустим, только один родитель на потомка).

Я могу сделать это следующим образом в модели:

has_one     :parent, :through => :relationships, :foreign_key => :human_id, :source => :source_human
has_many    :offsprings, :finder_sql =>
          'SELECT DISTINCT offsprings.* ' +
          'FROM humans offsprings INNER JOIN relationships r on ' +
          'r.human_id = offsprings.id where r.source_human_id = #{id}' 

Я должен был сделать это, потому что лучший способ сделать это:

 has_many    :offsprings, :through => :relationships, :foreign_key => :source_human_id, :source => :human

Невозможно, потому что внешние ключи игнорируются в has_many (согласно документации здесь: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many)

Однако теперь я получаю эту ошибку:

ПРЕДУПРЕЖДЕНИЕ ОТКЛОНЕНИЯ: на основе строк интерполяция ассоциации условия устарели. Пожалуйста, используйте вместо этого. Так, например, has_many: senior_friends,: условия => 'age> # {age}' должен быть изменен на has_many: senior_friends,: условия => proc {"age> # {age}"}. (вызывается из irb_binding в (irb): 1)

Однако, как бы я ни взламывал: условия здесь, похоже, что: finder_sql хочет участвовать. Какие-нибудь мысли?

Ответы [ 2 ]

35 голосов
/ 29 марта 2011

Что делать, если вы делаете

has_many    :offsprings, :finder_sql =>
          proc { "SELECT DISTINCT offsprings.* " +
          "FROM humans offsprings INNER JOIN relationships r on " +
          "r.human_id = offsprings.id where r.source_human_id = #{id}" }
5 голосов
/ 13 декабря 2013

На самом деле, я бы написал так:

has_many :offsprings, :finder_sql => proc {OFFSPRING_SQL % {id: id}}

OFFSPRING_SQL = "SELECT DISTINCT offsprings.*
                   FROM humans offsprings
                  INNER JOIN relationships r
                        ON r.human_id = offsprings_id
                        WHERE r.source_human_id = %{id}"

Я думаю, что это облегчает понимание ассоциации и упрощает редактирование открытого SQL.Он также использует преимущества строковой интерполяции параметров.

...