【发布时间】:2014-03-25 09:10:26
【问题描述】:
我正在使用 Ransack 提供数据过滤器。
主用户模型具有以下关联:
user has_many trips, through registrations
user's name=xyz and trip's name=abc 等基本搜索条件可以正常工作。
但我们的大多数条件都适用于否定,例如 user's name=xyz and trip's name=abc and trip's name != def 不能按预期工作。
我们正在努力寻找参加过 ABC 之旅但没有参加过 DEF 之旅的人。但是为上述查询生成的 SQL 会生成这个子句:WHERE (trips.name LIKE 'ABC') AND (trips.name NOT LIKE 'DEF')。这显然不起作用,因为 users 表是使用此子句进行左内连接的,并且 trip.ids 是为名称像 ABC 而不是像 DEF 的行生成的。
如何使用 Ransack 做到这一点?
更新:
如果搜索查询是“已出差的用户名为 'ABC'”,则生成的 SQL 很好:
SELECT DISTINCT users.* FROM users LEFT OUTER JOIN registrations ON registrations.user_id = users.id LEFT OUTER JOIN trips ON trips.id = registrations.batch_id WHERE (trips.name LIKE '%ABC%')
如果搜索查询是“参加过‘ABC’和‘DEF’旅行的用户”,如何做到这一点?我尝试了两种不同的方法:
- 两个单独的条件,名称 = 'ABC' 和名称 = 'DEF'。这是通过“匹配所有”完成的。 SQL 给出了 0 结果(显然),因为这是生成的:
SELECT DISTINCT users.* FROM users LEFT OUTER JOIN registrations ON registrations.user_id = users.id LEFT OUTER JOIN trips ON trips.id = registrations.batch_id WHERE ((trips.name LIKE '%ABC%' AND trips.name LIKE '%DEF%')) - 我改为尝试“匹配任何”。这给了这个:
SELECT DISTINCT users.* FROM users LEFT OUTER JOIN registrations ON registrations.user_id = users.id LEFT OUTER JOIN trips ON trips.id = registrations.batch_id WHERE ((trips.name LIKE '%ABC%' OR trips.name LIKE '%DEF%'))
第二个查询结果是那些上过ABC或DEF的用户。
为了补充这一点,我们想要这个查询:“使用 ABC 但未使用 DEF 的用户”。我尝试了两个条件(匹配所有):trip.name = ABC 和 trips.name 不像 DEF。这是生成的 SQL:
SELECT DISTINCT users.* FROM users LEFT OUTER JOIN registrations ON registrations.user_id = users.id LEFT OUTER JOIN trips ON trips.id = registrations.batch_id WHERE ((trips.name LIKE '%ABC%' AND trips.name NOT LIKE '%DEF%'))
上面的查询返回了去旅行 ABC 的人。它没有过滤掉做过 DEF 的人,因为查询显然是错误的。
【问题讨论】:
-
嗨,你能在这里分享一下整个搜索过滤条件,然后我可以帮助你更好的方法。
-
我已经使用搜索过滤器更新了原始问题。
-
是的,这个查询首先用'ABC'检查名字,然后检查结果数据,旅行的名字不应该是'DEF',所以我认为这个查询是正确的。
-
我同意最后一个查询是正确的。但是,如果我的用例是搜索“使用 ABC 但未使用 DEF 的用户”,我该如何使用 Ransack?
-
很抱歉踢了这个,但是你用 Ransack 解决了这个问题吗?我正在寻找完全相同的问题的解决方案。
标签: mysql sql ruby-on-rails ransack