Rails3 Active Admin-如何仅过滤满足集合中所有选中项目的记录 [英] Rails3 Active Admin - How to filter only records that meet all checked items in collection
问题描述
我与网络模型之间存在一对多的用户关联。我的架构信息的相关部分如下。
I have a one-to-many associaton of user to network model. The relevant parts of my schema information is as follows.
# == Schema Information
# Table name: users
#
# id :integer not null, primary key
# name :string(255)
#
# Table name: networks
#
# id :integer not null, primary key
# user_id :integer
# uid :string(255)
# name :string(255)
# pub_url :string(255)
我想使用的name属性过滤出具有特定多个网络的用户网络模型。例如,如果我检查facebook和foursquare作为过滤器,我想找回同时连接了facebook和foursquare的用户。我当前的实现是传递一个包含用户可以添加的网络名称的数组,如下所示。
I want to filter out users who have specific multiple networks using the name property of the network model. For example if I check facebook and foursquare as filters, I want to get back users who have connected both facebook and foursquare. My current implementation is to pass an array containing the names of networks a user can add as displayed below.
filter :networks_name, :as => :check_boxes,
:collection => %w(facebook twitter foursquare linkedin)
但这对过滤器使用OR条件,以任何选中的项目。我真正想要得到的是满足所有已检查项目的用户。
实现此目标的正确方法是什么?
This however uses an OR condition for the filters which retrieves users with any of the checked items. What I actually want to get is users who meet all the checked items. What's the right way of achieving this?
推荐答案
ActiveAdmin使用meta_search作为其过滤器( https://github.com/ernie/meta_search ):
ActiveAdmin uses meta_search for its filters (https://github.com/ernie/meta_search):
filter :networks_name_all,
:as => :check_boxes,
:collection => %w(facebook twitter foursquare linkedin)
在您的用户模型中:
scope :networks_names_all_in, -> names {
names.reduce(scoped) do |scope, name|
subquery = User.select('`users`.`id`').
joins(:networks).
where('networks.name = ?', name)
scope.where("`users`.`id` IN (#{subquery.to_sql})")
end
}
search_methods :networks_name_all_in
这将为您创建一个不错的SQL查询,
This will create a nice single SQL query for you, with proper joins and where conditions.
例如:
User.networks_name_all_in(["facebook", "twitter"])
将生成以下SQL请求:
will generate the following SQL request:
SELECT *
FROM `users`
WHERE `users`.`id` IN (SELECT `users`.`id`
FROM `users`
INNER JOIN `networks`
ON `networks`.`user_id` = `users`.`id`
WHERE `networks`.`name` = 'facebook')
AND `users`.`id` IN (SELECT `users`.`id`
FROM `users`
INNER JOIN `networks`
ON `networks`.`user_id` = `users`.`id`
WHERE `networks`.`name` = 'twitter')
更新:增加了功能范围。
更新2:使范围对范围合并问题具有弹性。
Update 2: Make scope resilient to scope merging problems.
这篇关于Rails3 Active Admin-如何仅过滤满足集合中所有选中项目的记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!