使用ransack通过关联对象过滤多个条件

时间:2014-03-25 09:10:27

标签: mysql sql ruby-on-rails 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')。这显然不起作用,因为users表与此子句左内连接,并且为名称为ABC而不是DEF的行生成trip.ids。

如何使用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'",如何做到这一点?我尝试了两种不同的方法:

  1. 两个独立的条件,名称=' 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%'))
  2. 我试过"匹配任何"代替。这给了这个: 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%'))
  3. 第二个查询结果是那些使用过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的人,因为查询显然是错误的。

1 个答案:

答案 0 :(得分:0)

已经旅行的用户' ABC'但不是在' DEF':

User.ransack(trips_name_eq: 'ABC', trips_name_not_eq: 'DEF').results