Rails - 查找不存在其他连接表的记录

Chr*_*len 1 activerecord ruby-on-rails

我正在尝试写一个ActiveRecord语句,我正在寻找其他表中不存在id的所有记录......

什么是语法?

 @events =  Event.find(:all, :include => :personals, 
                  :conditions => ["event.id != ? ", @user.personal.event_id ])
Run Code Online (Sandbox Code Playgroud)

personals是一个具有user_id和event_id的连接表....

所以我基本上试图找到用户没有添加到他们自己的个人记录集的每个事件记录....

有没有更好的方法来写这个....不是null或什么?

Gla*_*als 13

其他答案不能很好地扩展数十万或更多记录。这是一个纯 SQL 解决方案。

轨道 5+:

Event.left_outer_joins(:personals).where(personals: {event_id: nil})
Run Code Online (Sandbox Code Playgroud)

这将检索所有没有关联个人的事件。

轨道 3+:

Event.joins('LEFT JOIN personals ON event.id = personals.event_id').where('personals.event_id IS NULL')
Run Code Online (Sandbox Code Playgroud)


Joo*_*aij 8

Nuby提出的解决方案与以往一样正确.这是现代语法中的相同查询,可以在Rails 3及更高版本中使用:

Event.where.not(id: @user.event_ids)
Run Code Online (Sandbox Code Playgroud)

  • 这将生成大量(几乎肯定是非法的)select 语句,其中 id 仅包含在文本中。你确实需要一些可以连接的东西。 (2认同)

Nub*_*uby 7

我假设关系如下:

User: 
has_many :personals
has_many :events, :through => :personals

Event:
has_many :personals
has_many :users, :through => :personals

Personal:
belongs_to :event
belongs_to :user
Run Code Online (Sandbox Code Playgroud)

我的解决方案是使用自动创建的User"event_ids"关联函数,该函数列出了User.events中的所有事件ID.获取您要执行的操作的查询应该是:

Event.find(:all, :include => :personals, :conditions => ["events.id NOT IN (?)", @user.event_ids])
Run Code Online (Sandbox Code Playgroud)

而且,除非您确实需要加入,否则您可以简化:

Event.find(:all, :conditions => ["events.id NOT IN (?)", @user.event_ids])
Run Code Online (Sandbox Code Playgroud)

关键是SQL命令"NOT IN(x)".另外,请注意,根据SQL惯例,"events.id"对于模型名称是复数.

希望这可以帮助...

  • 这不会生成两个SQL命令 - 一个收集?`@ user.event_ids`,以及一个'不在[所有那些ids]中的那个`..这在很多情况下都很好,但是如果有数十万个`@ user.event_ids`,那么生成纯SQL的东西就是优选的; 对? (4认同)