Rails 添加两个具有活动记录结果的作用域 [英] Rails add two scope with active record result
问题描述
我使用的是作为可标记的 gem
I am using acts-as-taggable-on gem
我使用单个字段按 tag_name 和 user_name 进行搜索
i use single field to search by tag_name and 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",但它不起作用.
But i have pagination issue while getting this as Array and i used "will_paginate/Array" in config/initializer/will_paginate.rb it doesn't work.
用户控制器
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.search("best") => Should search by both tag_name and user_name and return ActiveRecord result.
我想得到 User.search("best") 与标签名 User.tagged_with("best") 联合的结果
i want to get the result of User.search("best") union with result of tag name User.tagged_with("best")
你能帮我将此范围添加为 ActiveRecord 关系,以便毫无问题地使用分页.
Can you help me to add this scopes as ActiveRecord relation to use pagination without issue.
推荐答案
我认为你只需要返回一个可链接的作用域(使用 .
而不是 +
):
I think you just need to return a chainable scope (use .
instead of +
):
where('name LIKE ?', "%#{search}%").tagged_with(search)
它返回一个 ActiveRecord::Relation
而不是 Array
.
It returns an ActiveRecord::Relation
instead of an Array
.
如果您需要执行 UNION
操作,我建议您关注此线程:ActiveRecord 查询联合.
If you need to perform an UNION
operation, I recommend you to follow this thread: ActiveRecord Query Union.
一种可能的方法是扩展 ActiveRecord:
One possible approach is to extend 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
这篇关于Rails 添加两个具有活动记录结果的作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!