2012-05-19 56 views
2

在我的模型中有父母,孩子和命名的孩子組。小組屬於父母,小孩屬於父母,小孩可能屬於同一父母的小組。Rails:渴望加載一個belongs_to:條件指的是自我

可能會刪除組,並稍後使用相同的名稱重新創建組,但使用不同的ID。一個孩子通過名字而不是id來引用它的組,所以如果該組被重新創建,它將屬於同一個組。同名的組可能存在於多個父母中,所以我們需要區分它們。

class Parent < ActiveRecord::Base 
    has_many :groups 
    has_many :children 
end 

class Group < ActiveRecord::Base 
    belongs_to :parent 

    has_many :children, 
    :foreign_key => :group_name, 
    :primary_key => :name, 
    :conditions => proc { "children.parent_id = #{self.parent_id}" } 
end 

class Child < ActiveRecord::Base 
    belongs_to :parent 

    belongs_to :group, 
    :foreign_key => :group_name, 
    :primary_key => :name, 
    :conditions => proc { "groups.parent_id = #{self.parent_id}" } 
end 

這工作很好,直到我試圖加載的兒童組。 Child.where(...).includes(:group)給出undefined method parent_id' for #<Class:0x00000002dcc290>。條件proc中的self是Child類,而不是Child對象。

我該如何加載這樣的關聯?或者,我的模型結構只是愚蠢的?這些組的複合主鍵已經越過了頭腦,但我寧可不要,因爲rails默認不支持。

回答

0

看起來像:finder_sql選項將工作has_many關係。不幸的是,這不是belongs_to關係的選項。

class Group < ActiveRecord::Base 
    belongs_to :parent 

    has_many :children, 
    :foreign_key => :group_name, 
    :primary_key => :name, 
    :finder_sql => proc { "select distinct children.id from children where children.parent_id = #{self.parent_id}" } 
end 
+0

不行的,抱歉:(鐵軌(eager-)加載組有獨立的「選擇.. 。FROM groups WHERE name IN(...)AND whatever-is-in--conditions'。查詢不引用children表。 – mpartel

+0

嗯,好吧,看起來像:finder_sql選項會做你想做的。 – Adam

+0

也不起作用Child中的belongs_to不使用finder_sql,根據文檔,不能使用:finder_sql和belongs_to。 – mpartel

0

我結束了手動編碼大約需要多少Rails會在急切加載:

class Child 
    def self.eager_load_groups(children) 
    keys = children.map {|c| 
     "(#{connection.quote(c.parent_id)}, #{connection.quote(c.group_name)})" 
    } 
    keys.uniq! 
    return if keys.empty? 

    groups = Group.where('(parent_id, name) IN (' + keys.join(',') + ')') 
    groups_by_key = Hash[groups.map {|g| [[g.parent_id, g.name], g] }] 

    for c in children 
     c.group = groups_by_key[[c.parent_id, c.group_name]] 
    end 
    end 
end