Rails模型查找不相等的地方


127

如何在不相等的条件下在数据库中查找记录?我现在有这个,但是有没有花哨的方式做到这一点?

GroupUser.where('user_id != ?',me)

我认为您所拥有的几乎是Rails 3的一种很好的实现方式。
Spyros

Answers:


229

在Rails 4.x中(请参阅http://edgeguides.rubyonrails.org/active_record_querying.html#not-conditions

GroupUser.where.not(user_id: me)

在Rails 3.x中

GroupUser.where(GroupUser.arel_table[:user_id].not_eq(me))

为了缩短长度,您可以将其存储GroupUser.arel_table在变量中,或者如果在模型GroupUser本身内部使用,例如,在中scope,可以使用arel_table[:user_id]代替GroupUser.arel_table[:user_id]

Rails 4.0语法归功于@jbearden的答案


社团中呢?-has_many:group_users,-> {where.not(status:“ Declined”)},通过::groups,foreign_key:“ user_id”
ajbraus 2014年

4
作为旁注,它还可以很好地链接:GroupUser.where(other_condition: true).where.not(user_id: user_id)
Enrico Carlesso 2014年


26

使其更出色的唯一方法是使用MetaWhere

MetaWhere有一个较新的表亲,称为Squeel,它允许这样的代码:

GroupUser.where{user_id != me}

不用说,如果这是您要进行的唯一重构,则不值得使用gem,而我只会坚持使用您得到的东西。Squeel在您有许多复杂的查询与Ruby代码交互的情况下很有用。


4
MetaWhere很棒,但是无需添加gem即可完成此任务。
tybro0103 2012年

1
@ tybro0103当然可以完成任务(并且恕我直言,OP的执行方式是完全可以的),但问题是执行起来比较完美。因此,如果您认为不用宝石就可以做得更好,那么我将对如何做到这一点非常感兴趣。
雅各布·汉普

Vikrant的答案确实提供了不涉及sql或不包含其他gem的解决方案。但是,我纠正了,您的答案肯定是最适合编码人员/最喜欢的。
tybro0103 2012年

1
添加宝石即可完成这样的简单任务。用火箭筒
打晕

这太过分了。
courtsimas

23

Rails 4:

如果你想使用这两个不相等,平等,你可以使用:

user_id = 4
group_id = 27
GroupUser.where(group_id: group_id).where.not(user_id: user_id)

(也就是说,如果你想使用多种经营的><),在某些时候,你可能希望符号切换到如下:

GroupUser.where("group_id > ? AND user_id != ?", group_id, user_id)

GroupUser.where(group_id: group_id).where.not(user_id: user_id)
Enrico Carlesso 2014年

@EnricoCarlesso感谢您的发帖。我更新了我的答案以包括您的建议。谢谢。
里克·史密斯

9

处理关联时,应始终在SQL查询中包括表名称。

的确,如果另一个表具有该user_id列,并且您将两个表连接在一起,则SQL查询中的列名将不明确(即麻烦)。

因此,在您的示例中:

GroupUser.where("groups_users.user_id != ?", me)

或更详细:

GroupUser.where("#{table_name}.user_id IS NOT ?", me)

请注意,如果您使用的是哈希,则不必担心,因为Rails会为您处理:

GroupUser.where(user: me)

如@ dr4k3所说,在Rails 4中,not已添加了查询方法:

GroupUser.where.not(user: me)

6

在Rails 3中,我什么都不懂。但是,我不确定您是否知道,您的不相等条件与(user_id)NULL值不匹配。如果需要,则必须执行以下操作:

GroupUser.where("user_id != ? OR user_id IS NULL", me)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.