我正在创建一个基于位置的应用程序,列出地图上的阅读程序。每个程序都有许多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关系,我需要在查询结束时添加一个分页调用。
答案 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[]
Program
个location = "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}}的位置不确定这是否属实,但应该让您到达某个地方。