2011-03-28 117 views
9

我已经钉牢了我想要的东西,但我似乎无法像钢轨设计师一样寻找它。基本上,我有(请留出多元化的/ etc的问题):Has_Many:通过或:finder_sql

人 关系(父母,后代)

我试图得到一个单亲家庭的所有子女,对于许多单亲后代(假设每个后代只有一位家长)。

我可以在模型下面的方式做到这一点:

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: String-based interpolation of association conditions is deprecated. Please use a proc instead. So, for example, has_many :older_friends, :conditions => 'age > #{age}' should be changed to has_many :older_friends, :conditions => proc { "age > #{age}" }. (called from irb_binding at (irb):1)

但是,无论我怎么破解:这里的条件,似乎并没有:finder_sql想参与。有什么想法吗?

回答

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

女士和病菌,获胜者。文档在这里是错误的,你不做:条件:finder_sql,你只是建立它。 – aronchick 2011-03-29 19:49:37

4

事实上,我会写这样说:

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