Rails 包括返回有限关系
Rails includes returning limited relations
我有一个搜索页面,用户可以在其中根据标签搜索事件。
我有以下方法return根据传递给该方法的标签 ID 编辑事件列表:
def self.tagged_with_id(taglist)
# convert taglist to an array if ids
taglist = taglist.chomp.split(',').map { |x| x.to_i }
#get tag name from each id
normalizedlist = taglist.collect{|id| Tag.find(id).name}
Event.includes([:tags]).where("tags.name IN (#{normalizedlist.map{|tagname| "'#{tagname}'"}.join(',')})")
end
...这是显示事件的视图...
<%- @events.each do |event| -%>
...
<td><div class="tag-wrapper"><%= display_tags(event.tags) %></div></td>
...
工作起来很有魅力,并且完全满足我的需要(大部分)。但是,我遇到的一个问题是在显示 event.tags
时的视图中,仅显示搜索到的标签。我希望每个事件的所有标签都显示在 returned.
的搜索结果中
如果我使用 tagged_with_id 方法查询事件,然后查看标签,我会得到这个...
2.1.5 :007 > e=Event.tagged_with_id('44').first
2.1.5 :008 > e.tags
=> [#<Tag id: 44, name: "winning"]
这是使用 rails 查找方法的同一事件...
2.1.5 :009 > e=Event.find 80
2.1.5 :010 > e.tags
=> [#<Tag id: 44, name: "winning">, #<Tag id: 91, name: "air">, #<Tag id: 114, name: "management">
我希望我的 tagged_with_id 方法能够 return 包含所有标签的事件,而不仅仅是搜索到的标签。
我会提供一个解决方案,但首先,让我们清理一下您的那个方法。首先,您一次找到一个标签,让我们在一个查询中找到它们:
normalizedlist = Tag.where(id: taglist).pluck :name
它做同样的事情,但全部在一个查询中,速度快得多。
然后让我们清理最后一个查询:
Event.includes(:tags).where tags: { name: normalizedlist }
这也与您之前所做的相同,但它使用更清晰的散列语法来匹配关系的条件,而且您不需要 join
列表。 ActiveRecord 知道当它获取一个数组作为您想要执行的值时 IN
.
最后,解决方案,因为最后一个查询只加载带有所选标签的事件,您需要重新加载 event
对象,以便它从分贝:
display_tags(event.reload.tags)
这将加载该事件的所有标签。
我有一个搜索页面,用户可以在其中根据标签搜索事件。
我有以下方法return根据传递给该方法的标签 ID 编辑事件列表:
def self.tagged_with_id(taglist)
# convert taglist to an array if ids
taglist = taglist.chomp.split(',').map { |x| x.to_i }
#get tag name from each id
normalizedlist = taglist.collect{|id| Tag.find(id).name}
Event.includes([:tags]).where("tags.name IN (#{normalizedlist.map{|tagname| "'#{tagname}'"}.join(',')})")
end
...这是显示事件的视图...
<%- @events.each do |event| -%>
...
<td><div class="tag-wrapper"><%= display_tags(event.tags) %></div></td>
...
工作起来很有魅力,并且完全满足我的需要(大部分)。但是,我遇到的一个问题是在显示 event.tags
时的视图中,仅显示搜索到的标签。我希望每个事件的所有标签都显示在 returned.
如果我使用 tagged_with_id 方法查询事件,然后查看标签,我会得到这个...
2.1.5 :007 > e=Event.tagged_with_id('44').first
2.1.5 :008 > e.tags
=> [#<Tag id: 44, name: "winning"]
这是使用 rails 查找方法的同一事件...
2.1.5 :009 > e=Event.find 80
2.1.5 :010 > e.tags
=> [#<Tag id: 44, name: "winning">, #<Tag id: 91, name: "air">, #<Tag id: 114, name: "management">
我希望我的 tagged_with_id 方法能够 return 包含所有标签的事件,而不仅仅是搜索到的标签。
我会提供一个解决方案,但首先,让我们清理一下您的那个方法。首先,您一次找到一个标签,让我们在一个查询中找到它们:
normalizedlist = Tag.where(id: taglist).pluck :name
它做同样的事情,但全部在一个查询中,速度快得多。
然后让我们清理最后一个查询:
Event.includes(:tags).where tags: { name: normalizedlist }
这也与您之前所做的相同,但它使用更清晰的散列语法来匹配关系的条件,而且您不需要 join
列表。 ActiveRecord 知道当它获取一个数组作为您想要执行的值时 IN
.
最后,解决方案,因为最后一个查询只加载带有所选标签的事件,您需要重新加载 event
对象,以便它从分贝:
display_tags(event.reload.tags)
这将加载该事件的所有标签。