2011-08-21 35 views
0

什么是解决这类查询的最佳方式:的has_many:通过查询基础上,“桥”模型的财产

  • 每个组都有很多地区
  • 每个州都有许多地区
  • 每组通过各区
  • 每个区都属于一个成员都有许多国家

集团1 - *区(属于一个成员)* - 1州

我想查找一个特定组的状态列表,其中其区域的至少一个未分配给成员(即,区的member_id为空)。换句话说,如果该州的所有地区都被分配给一个会员,那么该州就不会出现在我的名单中。

class State < ActiveRecord::Base 
has_many :districts 
end 

class Group < ActiveRecord::Base 
has_many :districts 
has_many :states, :through => :districts, :uniq => true 
end 

class District < ActiveRecord::Base 
belongs_to :state 
belongs_to :group 
belongs_to :member 
end 

我想要在我看来做到的是让用户首先选择他的组,然后选择他想从工作状态,最后是基于他的研究小组填充可用区,状态选择。所以基本上我不希望州列表包括没有可用区的州。

编辑:

,我想出了一个可行的办法是在我Group类来定义新的方法,请告诉我,如果这是一个很好的解决方案:

class Group < ActiveRecord::Base 

... 

    def available_states 
    result = [] 
    self.states.each do |state| 
     state_list = state.districts & self.districts.where(:member_id => nil) 
     if !state_list.empty? 
     result << state 
     end 
    end 
    result 
    end 

end 

回答

2

我觉得你过于复杂的事情。

你说你希望用户选择自己,再状态。那么为什么你需要筛选每个州的全区名单?你已经有了该组可能的地区列表,不是吗?如果您针对每个州的地区&,那么您最终只能进入该群组的各个区域。

看来,这就够了:

def available_states 
    districts.where(:member_id => nil).group(:state_id).map(&:state) 
end 

还是我失去了一些东西?

纯粹的未经检验的,但你也可以尝试这样的事:

class District 
    # this scope is simple, but keeps the "available" definition where it 
    # belongs, in District 
    scope :available, lambda { where(:member_id => nil) } 
end 

class State 
    # then here just join "available" districts and group on id for uniqueness 
    scope :with_available_districts, lambda { 
    joins(:districts).group(:id) & District.available 
    } 
end 

# now you don't need an available_states method, it would just be: 
Group.first.states.with_available_districts 
+0

好看起来神奇公式使用。集团和.map,两种方法我不知道会解决我的问题!谢谢。现在我要尝试使用示波器的想法! – cyehia

+0

尼斯:-)希望它能解决问题 – numbers1311407