如何组合来自多个has_many的ActiveRecord结果:通过查询?

时间:2012-07-19 20:05:45

标签: ruby-on-rails ruby activerecord

基本上,我有一个带有标记系统的应用程序,当有人搜索标签'badger'时,我希望它返回标记为“badger”,“Badger”和“Badgers”的记录。 使用单个标签,我可以这样做以获取记录:

@notes = Tag.find_by_name(params[:tag_name]).notes.order("created_at DESC")

它工作正常。但是,如果我得到多个标签(这只是大写和小写 - 我还没有想出's'位):

Tag.find(:all, :conditions => [ "lower(name) = ?", 'badger'])

我不能使用.notes.order(“created_at DESC”)因为有多个结果。 所以,问题是...... 1)我是否正确地采取了这种方式? 2)如果是这样,我如何按顺序恢复所有记录?

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:3)

一种实现方式是:

@notes = []
Tag.find(:all, :conditions => [ "lower(name) = ?", 'badger']).each do |tag|
  @notes << tag.notes
end
@notes.sort_by {|note| note.created_at}

但是你应该知道这就是所谓的N + 1查询,因为它在外部区域中进行一次查询,然后在每个结果中进行一次查询。可以通过将第一个查询更改为:

来优化
Tag.find(:all, :conditions => [ "lower(name) = ?", 'badger'], :includes => :notes).each do |tag|

如果您使用的是Rails 3或更高版本,可以稍微重写一下:

Tag.where("lower(name) = ?", "badger").includes(:notes) do |tag|

答案 1 :(得分:0)

<强>被修改

首先,获取所有可能标记名称的数组,复数,单数,低位和高位

tag_name = params[:tag_name].to_s.downcase
possible_tag_names = [tag_name, tag_name.pluralize, tag_name.singularize].uniq
# It's probably faster to search for both lower and capitalized tags than to use the db's `lower` function
possible_tag_names += possible_tag_names.map(&:capitalize)

您使用的是标记库吗?我知道有些提供了查询多个标签的方法。如果您没有使用其中一个,则需要在查询中执行一些手动SQL连接(假设您使用的是MySQL,Postgres或SQLite等关系数据库)。我很乐意为此提供帮助,但我不知道你的架构。