Rails - Найти записи, которых нет в другой таблице соединений - PullRequest
1 голос
/ 27 января 2011

Я пытаюсь написать отчет ActiveRecord, где я ищу все записи, в которых идентификатор отсутствует в другой таблице ...

Какой синтаксис?

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

Где Personals - это таблица соединений, в которой есть user_id и event_id ....

Так что я по сути пытаюсь найти каждую запись события, которую пользователь не добавил в свой собственный набор личных записей....

Есть ли лучший способ написать это .... не нуль или что-то еще?

Ответы [ 3 ]

7 голосов
/ 20 апреля 2015

Решение, представленное Nuby, как никогда верно.Вот тот же запрос в современном синтаксисе, который можно использовать в Rails 3 и выше:

Event.where.not(id: @user.event_ids)
7 голосов
/ 27 января 2011

Я предполагаю, что отношения следующие:

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

Мое решение состоит в том, чтобы использовать автоматически созданную функцию ассоциации для пользователя "event_ids", которая перечисляет все идентификаторы событий в User.events.Запрос, чтобы получить то, что вы пытаетесь сделать, должен быть:

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

И, если вам действительно не нужно объединение, вы можете упростить:

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

Ключ - это SQLКоманда «НЕ В (х)».Кроме того, обратите внимание, что «events.id» является множественным числом для имени модели, в соответствии с соглашением SQL.

Надеюсь, это поможет ...

1 голос
/ 29 августа 2018

Другие ответы плохо масштабируются с сотнями тысяч и более записей. Вот чистое решение SQL.

Рельсы 5:

Event.left_outer_joins(:personals).where(personals: {event_id: nil})

При этом извлекаются все события, не связанные с личным.

Рельсы 3 +:

Event.joins('LEFT JOIN personals ON event.id = personals.event_id').where('personals.event_id IS NULL')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...