【问题标题】:Rails add two scope with active record resultRails 添加了两个具有活动记录结果的范围
【发布时间】:2015-10-21 12:31:39
【问题描述】:

我正在使用作为可标记的 gem

我使用单个字段按 tag_name 和 user_name 搜索

用户.rb

class User < ActiveRecord::Base

  acts_as_taggable
  attr_accessor: :user_name, :age, :country, tag_list
  scope :tagged_with, lambda { |tag|
    {
      :joins => "INNER JOIN taggings ON taggings.taggable_id = user.id\
               INNER JOIN tags ON tags.id = taggings.tag_id AND taggings.taggable_type = 'User'",
      :conditions => ["tags.name = ?", tag],
      :order => 'id ASC'
    }
  }
  def self.search(search)
    if search
      where('name LIKE ?', "%#{search}%") + tagged_with(search)
    else
      scoped
    end
  end
end

但我在将它作为数组获取时遇到了分页问题,​​我在 config/initializer/will_paginate.rb 中使用了“will_paginate/Array”,但它不起作用。

用户控制器

class UserController < ActionController::Base
  def index
    @users = User.search(params[:search]).paginate(:per_page => per_page, :page => params[:page])
  end

控制台。

User.search("best") => 应该同时按 tag_name 和 user_name 搜索并返回 ActiveRecord 结果。

我想用标签名 User.tagged_with("best") 得到 User.search("best") 联合的结果

您能帮我将此范围添加为 ActiveRecord 关系,以便毫无问题地使用分页。

【问题讨论】:

  • 我认为您的范围可以重写为:scope :tagged_with, lambda { |tag| joins(:tags).where(tags: { name: tag }).order('users.id ASC') })

标签: ruby-on-rails ruby ruby-on-rails-3 rails-activerecord acts-as-taggable-on


【解决方案1】:

我认为你只需要返回一个可链接的范围(使用. 而不是+):

where('name LIKE ?', "%#{search}%").tagged_with(search)

它返回 ActiveRecord::Relation 而不是 Array

如果您需要执行UNION 操作,我建议您关注此线程:ActiveRecord Query Union

一种可能的方法是扩展 ActiveRecord:

module ActiveRecord::UnionScope
  def self.included(base)
    base.send(:extend, ClassMethods)
  end

  module ClassMethods
    def union_scope(*scopes)
      id_column = "#{table_name}.id"
      sub_query = scopes.map { |s| s.select(id_column).to_sql }.join(" UNION ")
      where("#{id_column} IN (#{sub_query})")
    end
  end
end 

用法(未测试):

class User < ActiveRecord::Base
  include ActiveRecord::UnionScope

  def self.search(search)
    if search
      union_scope(where('name LIKE ?', "%#{search}%"), tagged_with(search))
    else
      scoped
    end
  end
end

【讨论】:

  • 感谢您的回复。我想用标签名称 User.tagged_with("best") 得到 User.search("best") 联合的结果。
  • 感谢您的回答。它在我的控制台上工作得很好。现在我得到这个错误stackoverflow.com/questions/33281995/…。请帮忙。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-02
  • 1970-01-01
相关资源
最近更新 更多