2015-11-10 3 views
0

У меня есть эти таблицы:Rails 4 + ActiveRecord: как исключить некоторые записи из поиска?

  1. users - классический стол DEViSE
  2. listings - пользователи создание списков
  3. listings_exclude_users - 2 колонки: user_id и listing_id

user.rb

class User 
    has_many :listings 
end 

listing.rb

class Listing 
    belongs_to :user 
    has_many :listing_excluded_users 
end 

listing_excluded_user.rb

class ListingExcludedUser 
    belongs_to :user 
    belongs_to :listing 
end 

помечать некоторые пользователи, для которых не должна быть соответствующая реклама видна и эта информация сохраняется в listings_exclude_users.

Теперь я хотел бы запустить запрос, который будет извлекать все списки, но если подписанный пользователь, который находится в таблице listings_exclude_users за конкретным листингом, то не извлекайте это объявление.

Я могу сделать это на виду, но я бы предпочел путь ActiveRecord. Я попытался

@listings = Listing.joins(:listing_excluded_users).where("listings.status='0' AND (listing_excluded_users.user_id != '#{current_user.id}')") 

Но этот запрос ничего (пустой @listings) не возвращается.

Благодарим вас за консультацию.

+0

какая база данных вы используете? MySQL? Postgres? –

+0

Я использую MySQL. – user984621

+0

Никогда, никогда не делайте что-то вроде «... # {varname}» в фрагменте SQL. Возможно, на сей раз вы в безопасности, но в какой-то момент вы получаете инъекцию SQL. Вы должны научиться использовать параметры в инструкции SQL. – Meier

ответ

0

Это легко сделать в двух запросах. Если вам нужен один запрос, вам может понадобиться подзапрос.

2 запросы:

user_ids_to_exclude = ListingExcludedUser.where.not(user_id: current_user.id).pluck(:user_id) 
@listings = Listing.where.not(user_id: user_ids_to_exclude) 

подзапросов

@listings = Listing.where.not(user_id: ListingExcludedUser.where.not(user_id: current_user.id).select(:user_id)) 

Примечание: where.not является Rails 4 идиома.

+0

Спасибо, 'Питер', за ваш ответ. Однако как этот запрос отличается от этого в OP? Во всяком случае, проблема в том, что вывод представляет собой пустой массив. Если у меня есть 10 записей в таблице БД, и я решил, что не хочу, чтобы первая была видимой для пользователя, остальные 9 должны отображаться там. – user984621

+0

Ключ «<>», а не «! =». Вот как вы НЕ в sql. –

+0

Я уверен, что проблема заключается в типе соединения, которое вы делаете. Сделав внутреннее соединение, вы исключите строки, которые не находятся в таблице исключений, что является противоположностью того, что вы хотите! См. Мое редактирование выше, чтобы использовать OUTER JOIN. –