【问题标题】:has_many :through query based on the 'bridge' model's propertyhas_many :通过基于“桥”模型属性的查询
【发布时间】:2011-08-21 19:37:12
【问题描述】:

解决此类查询的最佳方法是什么:

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

Group 1 -- * District (属于一个成员) * -- 1 State

我想查找特定组的州列表,其中 至少有一个 的地区没有分配给成员(即地区的 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

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3


    【解决方案1】:

    我觉得你把事情复杂化了。

    您说您希望用户首先选择他们的,然后是状态。那么为什么需要过滤每个州的完整地区列表呢?您已经有了小组中可能的地区列表,不是吗?如果你 &amp; 反对每个州的地区,那么你最终会得到该组织的地区。

    看来这就够了:

    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
    

    【讨论】:

    • 看起来神奇的公式正在使用 .group 和 .map,我不知道的两种方法可以解决我的问题!谢谢。现在我将尝试使用范围来尝试您的想法!
    猜你喜欢
    • 2011-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多