Ruby on rails 如何检查联接上的条件?
我正在尝试在我的小部件搜索中为用户设置过滤。我希望他们能够点击一些标签,并且只返回应用了正确标签的结果 各表的设置如下:Ruby on rails 如何检查联接上的条件?,ruby-on-rails,ruby,Ruby On Rails,Ruby,我正在尝试在我的小部件搜索中为用户设置过滤。我希望他们能够点击一些标签,并且只返回应用了正确标签的结果 各表的设置如下: 小部件有许多标记,通过标记 通过标记,标记有许多小部件 标记是一个联接表 在我的控制器中,我迭代小部件,并检查标记连接的条件: @widgets = Widget.all @current_tags = [1,5,7,10,15] # Passed in from params @current_tags.each do |t| @widgets = @widgets
- 小部件有许多标记,通过标记
- 通过标记,标记有许多小部件
- 标记是一个联接表
@widgets = Widget.all
@current_tags = [1,5,7,10,15] # Passed in from params
@current_tags.each do |t|
@widgets = @widgets.joins(:tags).where("tags.id=?", t)
end
我只希望返回具有所有这些标记的小部件
这对于一个标记似乎很好,但一旦单击另一个标记,一旦选择了多个标记,就会产生问题。例如,这将按预期返回小部件1:
# Widget 1 is joined to tags 1,5,7,9
@current_tags = [5]
这不会返回任何结果,即使它应该返回小部件1:
# Widget 1 has tags 1,5,7,9
@current_tags = [5,7]
我在检查标记和小部件之间的连接时是否做错了什么?您可能对gem上作为标记的行为感兴趣,但对于您的问题,这是一个棘手的问题!当然,您可以使用一个强大的Rails习惯用法,但这里有一个蛮力方法:
unless @current_tags.empty?
# set initial state to widgets that match the first tag
@widgets = @widgets.joins(:tags).where("tags.id=?", @current_tags.shift)
@current_tags.each do |t|
# then keep only widgets in initial state AND the next tag
@widgets &= @widgets.joins(:tags).where("tags.id=?", t)
end
end
您希望将查询更改为:
@current_tags = [1,5,7,10,15]
@widgets = Widget.joins(:tags).where("tags.id IN (?)", @current_tags)
它正在按用户选择的标签查找小部件。如果每个小部件仅链接一次标签,您可以执行以下操作:
@widgets=
小装置
.select('widgets.id')
.joins(“taggings.widget上的内部连接标记\u id=widgets.id”)
.where(tag_id:@current_tags)
.group(“widgets.id”)
.具有(“计数(*)={@current_tags.length}”)
编写此代码的另一种方法:
widget\u id=
标记
.选择(:小部件\u id)
.where(tag_id:@current_tags)
.group(:小部件\u id)
.具有(“计数(*)={@current_tags.length}”)
@widgets=Widget.where(id:Widget\u id)
一种有点尴尬的方法是,使您的循环链位于顶部,如下所示:
@widgets = Widget.all
@current_tags = [1,5,7,10,15]
@current_tags.each do |t|
@widgets = @widgets.where(
widget.taggings.where(tag_id: t).exists # << a bit of Arel for ya
)
end
@widgets=Widget.all
@当前_标签=[1,5,7,10,15]
@当前|u标记。每个标记都有| t|
@widgets=@widgets.where(
widget.taggings.where(tag_id:t).exists#这会给您一个OR,海报要求提供AND:“我只希望返回具有所有这些标记的widget。”