Rails包括返回有限的关系

时间:2015-01-20 15:00:24

标签: ruby-on-rails ruby-on-rails-3.2

我有一个搜索页面,用户可以根据标签搜索事件。

我有以下方法返回基于传递给方法的标记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时的视图中,仅显示正在搜索的标记。我希望每个事件的所有标签都显示在返回的搜索结果中。

如果我使用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 find方法的相同事件......

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方法能够返回包含所有标签的事件,而不仅仅是搜索过的标签。

1 个答案:

答案 0 :(得分:1)

我会提供一个解决方案,但首先,让我们清理你的方法。首先,您一次找到一个标签,让我们在一个查询中找到它们:

normalizedlist = Tag.where(id: taglist).pluck :name

同样的事情,但在一个查询中,更快。

然后让我们清理最后一个查询:

Event.includes(:tags).where tags: { name: normalizedlist }

这也和以前一样,但是它使用了更清晰的哈希语法来匹配关系的条件,你也不需要join列表。 ActiveRecord知道当它将数组作为您想要执行IN的值时。

最后,解决方案,因为最后一个查询仅加载具有所选标记的事件,您需要重新加载event对象,以便从db加载其所有tags

display_tags(event.reload.tags)

这将加载该事件的所有标记。