2012-04-30 3 views
1

У меня есть следующая область видимости в модели Rails.Где НЕ IN() на соединении?

class Suggestion < ActiveRecord::Base 
    has_many :favourites 

    def self.favoured_by(user) 
    joins(:favourites).where(favourites: { user_id: user.id }) 
    end 
end 

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

Как я могу получить все предложения, которые либо не предназначены для всех или которые используются, а не этим конкретным пользователем?

def self.not_favoured_by(user) 
    # ... 
end 

Моя Favourite модель выглядит следующим образом:

class Favourite < ActiveRecord::Base 
    belongs_to :suggestion 
    belongs_to :user 
end 
+0

Не могли бы вы также разместить свой 'favourite' модель? –

+0

Почему вы не делаете связь has_many trough вместо этого соединения? –

+0

@ismaelga @PaulSimpson Я добавил свою модель «Фаворит» к OP. 'Favourite' должен быть моделью объединения между' User' и 'Suggestion', потому что пользователь может использовать любимые предложения, принадлежащие другим пользователям. –

ответ

4
favorited_suggestions_ids = joins(:favourites).where(favourites: { user_id: user.id }).map(&:id) 
return scoped if favorited_suggestion_ids.empty? 
where('id not in (?)',favorited_suggestions_ids) 
+0

'ActiveRecord :: StatementInvalid: SQLite3 :: SQLException: неоднозначное имя столбца: id: SELECT« предложения ». * FROM« предложения »INNER JOIN« избранное »ВКЛ« избранное ».« Suggestion_id »=« предложения ».« Id » WHERE (id not in (2)) ORDER BY created_at DESC'. Моя первая мысль заключалась в том, чтобы префикс 'id' был« предложениями », но это, похоже, не работает. –

+0

Вы делали 'suggestion_id не в (?)' И '.map (&: suggestion_id)'? Я не был уверен, что такое id –

+0

На самом деле, я думаю, вам не нужно соединение во втором запросе, потому что вам не нужны избранные. Отредактировал мой ответ. Проблема должна быть решена. Ошибка была в том, что в этом соединении были предложения.id и favourites.id, поэтому путем двусмысленности это означает, что есть более одного идентификатора для выбора –

0

Как об этом:

def self.not_favoured_by(user) 
    sql = <<-SQL 
    SELECT suggestions.* FROM suggestions 
    WHERE NOT EXISTS 
     (SELECT id FROM favourites WHERE user_id = #{user.id} AND favourites.suggestion_id = suggestions.id); 
    SQL 
    find_by_sql(sql) 
end 
+0

Хотя эта версия работает, я предпочитаю версию без raw-SQL, поэтому я принимаю ее. –

Смежные вопросы