Rails - HABTM Relationship - Как мне найти запись, основанную на атрибуте ассоциированной модели - PullRequest
35 голосов
/ 14 января 2011

Я установил эти отношения HABTM в прошлом, и они работали раньше .... Теперь это не так, и я в своем уме, пытаясь выяснить, что не так. Я просматриваю направляющие весь день и, похоже, не могу понять, что я делаю неправильно, поэтому помощь будет очень признательна.

У меня есть 2 модели, связанные через модель соединения, и я пытаюсь найти записи на основе атрибута связанной модели.

Event.rb

has_and_belongs_to_many :interests

Interest.rb

has_and_belongs_to_many :events

и миграция таблицы соединений, которая была создана как

  create_table 'events_interests', :id => false do |t|
      t.column :event_id, :integer
      t.column :interest_id, :integer
   end

Я пытался

 @events = Event.all(:include => :interest, :conditions => [" interest.id = ?", 4 ] )

Но получил ошибку «Ассоциация под названием« интерес »не найдена; возможно, вы ошиблись?» ... что я, конечно, не сделал

Я пытался

  @events = Event.interests.find(:all, :conditions => [" interest.id = ?", 4 ] )

но получил ошибку "неопределенный метод" интересуется "для #Class: 0x4383348"

Как я могу найти события с идентификатором интереса 4 ... Я определенно облысел от этого смеха

Ответы [ 2 ]

76 голосов
/ 14 января 2011

Вам необходимо включить таблицу интересов.

@events = Event.all(:include => :interests, :conditions => ["interests.id = ?", 4])

Вы правильно указали в своем сообщении, но не указали плюрализм интересов.

Обновление

Поскольку этот ответ по-прежнему привлекает внимание, я подумал, что было бы неплохо обновить его, используя синтаксис ActiveRecord::Relation, поскольку вышеприведенный способ устарел.

@events = Event.includes(:interests).where(interests: { id: 4 })

или

@events = Event.includes(:interests).where('interests.id' => 4)
7 голосов
/ 08 октября 2015

Ответ был полезен, спасибо!Я знаю, что этот пост старый, но я нашел другое решение, которое может быть кому-то полезно.Я заметил, что генерация запроса была довольно длинной в моем случае.Для меня таблица, которая была сопоставима с вашей таблицей "интересов", имела много столбцов и данных.Чтобы избежать поиска в этой таблице соответствующих идентификаторов, мое решение выглядело примерно так:

@events = Event.all.where('events.id' => @interest.events.each(&:id)) 

Это сработало для меня, поскольку у меня уже был инстанцированный объект @interest со списком идентификаторов событий.Конечно, вы не используете ту магию, которая есть у рельсов.Кроме того, я не мог заставить ваше решение работать с "нет".Например,

@events = Event.includes(:interests).where.not(interests: { id: 4 })

не будет работать.Это возвратило бы 0 результатов.Но это:

@events = Event.all.where.not('events.id' => @interest.events.each(&:id)) 

будет работать, что вернет все события, которые не связаны с @ Interest.

...