ActiveRecord - 通过嵌套的has_many搜索:through

时间:2014-05-02 13:07:50

标签: ruby ruby-on-rails-4 rails-activerecord

我正在创建一个基于位置的应用程序,列出地图上的阅读程序。每个程序都有许多age_groups(通过program_age_groups)并且有许多位置(通过program_locations)。对于搜索结果,我需要列出符合用户标准的每个program_location。我创建了一个搜索模型,通过search_age_groups也有很多age_groups。我的问题是,如何根据相关程序的age_group_ids过滤程序位置?我可以通过在搜索模型中执行类似的操作来实现它:

program_locations = ProgramLocation.all.includes(program: :age_groups)
program_locations = program_locations.where(age_groups: self.age_group_ids)

但是,这会在age_group_ids上创建一个join语句,当我遍历程序位置并列出程序的详细信息时,只显示与搜索年龄组匹配的年龄组。即使该程序具有其他年龄组,它们也仅在用户选择搜索中的年龄组时显示,或者如果搜索时年龄组字段为空。

编辑:澄清

例如,假设程序1的age_groups为0-2和3-5,而程序2的age_group为6-10。用户进行搜索并仅选择age_group 0-2。当我显示结果时,它将正确过滤掉程序2,但它将显示:

计划1 年龄组:0-2

何时显示

计划1 年龄组:0-2,3-5

有什么想法吗?这似乎是一个常见的问题,我在过去遇到过类似的问题,但我似乎无法找到一个直接的解决方案。我尝试使用拒绝,但这不会返回activerecord关系,我需要在查询结束时添加一个分页调用。

1 个答案:

答案 0 :(得分:0)

你可以像这样对它们进行调整:

class Program
   has_many :program_age_groups
   has_many :age_groups, through: :program_age_groups
   has_many :program_locations
   has_many :locations, through: :program_locations

   scope :by_age_group,->(age_group){ 
                          program_ids = program_age_groups.where(age_group: age_group).pluck(:program_id)
                          where(id: program_ids)
                         }
   scope :by_location,->(location){
                          program_ids = program_locations.where(location: location).pluck(:program_id)
                          where(id: program_ids)
                          }

end

然后用

打电话
age_groups = ['0-2']
Program.by_age_group(age_groups)

这将返回具有指定年龄段的ActiveRecord::Relation[] Programlocation = "Some location" age_groups = ['0-2'] Program.by_location(location).by_age_group(age_groups) 。 或者

scopes

class ProgramLocation belongs_to :program belongs_to :location scope :by_age_group,->(age_group){ program_ids = Program.by_age_group(age_group).pluck(:id) where(program_id: program_ids) } scope :by_location,->(location){ location_ids = Location.where(name: location).pluck(:id) where(location_id: location_ids } end 是一个非常强大的工具,我发现它们对搜索特别有用,因为你可以很好地将它们链接在一起,同时保持可读性。

<强>更新

name

这假设您在作用域中搜索的属性{{1}}的位置不确定这是否属实,但应该让您到达某个地方。