Has_Many:通过或:finder_sql

时间:2011-03-28 22:13:06

标签: ruby-on-rails ruby ruby-on-rails-3 has-many-through

我已经确定了我想要的东西,但我似乎无法以导轨设计师正在寻找的方式获得它。基本上,我有(请留出多元化/等问题):

人类 关系(父母,后代)

我正试图让单亲的所有后代,以及许多后代的单亲(假设每个后代只有一位父母)。

我可以在模型中以下列方式执行此操作:

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

然而,现在我收到了这个错误:

  

DEPRECATION WARNING:基于字符串   关联插值   条件已弃用。请用一个   相反。所以,例如,   has_many:older_friends,:条件   => '年龄> #{age}'应更改为has_many:older_friends,:conditions   => proc {“age>#{age}”}。 (从(irb)的irb_binding调用:1)

然而,无论我如何破解:条件在这里,它似乎没有:finder_sql想要参与。有什么想法吗?

2 个答案:

答案 0 :(得分:35)

如果你这样做

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}" }

答案 1 :(得分:5)

实际上,我是这样写的:

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更容易编辑。它还利用了基于字符串的参数插值。