Как найти все предметы, не связанные с другой моделью - Rails 3 - PullRequest
1 голос
/ 13 июля 2010

У меня довольно сложный поиск, который я пытаюсь сделать в Rails, и я не совсем уверен, как кто-то может помочь.

У меня есть две модели, Пользователь и Место.

Пользователь связан с местом дважды.Один раз для посещенных мест и один раз для запланированных мест.Это отношение многих ко многим, но с использованием has_many: through.Вот отношения от пользователя.

has_many :visited_places
has_many :visited, :class_name=>"Place", :through=>:visited_places, :source=>:place

has_many :planned_places
has_many :planned, :class_name=>"Place", :through=>:planned_places, :source=>:place

На месте отношения также определены.Вот определение там

has_many :visited_users, :class_name=>"User", :through=>:visited_places  
has_many :planned_users, :class_name=>"User", :through=>:planned_places

Я пытаюсь написать находку на Месте, которая возвращает все места в базе данных, которые не связаны с Пользователем через посещенных или запланированных.Прямо сейчас я выполняю это, просто запрашивая все места и затем вычитая посещенные и запланированные из результатов, но я хочу добавить в нумерацию страниц, и я боюсь, что это может усложнить это.Вот мой текущий код.

all_places = Place.find(:all)        
all_places = all_places - user.visited - user.planned

Кто-нибудь знает, как мне это сделать, просто позвонив на Place.find.Также это приложение на Rails 3, так что если какие-либо улучшения активных записей делают это проще, они являются опцией.

Ответы [ 4 ]

2 голосов
/ 13 июля 2010

Как насчет чего-то вроде:

unvisited_places = Place.find(:all, :conditions => "id NOT IN(#{visited_places.map(&:place_id)})")

Это общая идея - ее можно сделать более эффективной и удобной в зависимости от ваших конечных потребностей.

0 голосов
/ 12 августа 2014

Недавно я столкнулся с аналогичным желанием ... Я хотел получить все Model1, которые не были связаны с Model2. Используя Rails 4.1, вот что я сделал:

Model1.where.not(id: Model2.select(:user_id).uniq)

Это создает вложенный SELECT, как предложено @nathanvda, эффективно позволяя базе данных выполнять всю работу. Пример созданного SQL:

SELECT "model1s".* FROM "model1s"  WHERE ("model1s"."id" NOT IN (SELECT DISTINCT "model2s"."model1_id" FROM "model2s"))
0 голосов
/ 14 июля 2010

в sql:

select * from places where id not in 
  (
    (select place_id from visited_places where user_id = ?) 
  union 
    (select place_id from planned_places where user_id=?)
  )

Если этот запрос работает, вы можете использовать следующее:

Places.find_by_sql(...the complete sql query ...)

Я бы не знал, как написать такой запрос, за исключением:в Rails 3 иначе.

0 голосов
/ 14 июля 2010

Вы не показываете это, но если я прав, предполагая, что модели VisitedPlace и PlannedPlace имеют отношения belongs_to :user, тогда эти таблицы имеют вторичный ключ user_id, верно?

Так что в этом случае я думаю, что было бы наиболее эффективно сделать это в базе данных, и в этом случае вы ищете выборку по объединению таблиц places, visited_places и planned_places где users.id не входит ни в visited_places, ни в planned_places

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...