我正在使用Ransack提供数据过滤器。使用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')
。这显然不起作用,因为用户表与此子句是左内连接的,trip.id是针对名称类似ABC的行生成的,并不像DEF。
如何使用Ransack做到这一点?
UPDATE:
如果搜索查询,生成的SQL“谁拥有了名为‘ABC’之旅用户”是好的: 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的人,因为查询显然是错误的。
你好,可以请你在这里分享整个搜索过滤条件,那么我可以帮你更好的办法。 –
我已经使用搜索过滤器更新了原始问题。 – sridharraman
是的,这个查询首先检查'ABC'的名字,然后检查结果数据,旅行的名字不应该'DEF',所以我认为这个查询是正确的。 –