web-dev-qa-db-ja.com

HABTMの関係-関連するモデルの属性に基づいてレコードを見つけるにはどうすればよいですか

私はこれを設定しました[〜#〜] habtm [〜#〜]過去に関係を設定しましたが、以前は機能していました。何が悪いのかを理解します。 Railsガイドを一日中調べましたが、何が間違っているのか理解できないようですので、助けていただければ幸いです。

結合モデルを介して接続された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 ] )

しかし、エラーが発生しました:

「「interest」という名前の関連付けが見つかりませんでした。スペルを間違えた可能性がありますか?」...

コースから外れませんでした。

私は試した:

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

しかし、エラーが発生しました:

「#Class:0x4383348の未定義のメソッド「interests」」

インタレストIDが4のイベントを見つけるにはどうすればよいですか...私は間違いなくこの笑からハゲになります

36
ChrisWesAllen

インタレストテーブルを含める必要があります。

@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)

そして、カスタム条件が必要な場合

@events = Event.includes(:interests).where('interests.id >= 4')
81
Sean Hill

答えは役に立ちました、ありがとう!私はこの投稿が古いことを知っていますが、誰かに役立つかもしれない別の解決策を思いつきました。私の場合、クエリの生成が非常に長いことに気づきました。私にとって、あなたの「興味」テーブルと同等のテーブルには、たくさんの列とデータが含まれていました。そのテーブルで一致するIDを検索しないようにするために、私のソリューションは次のようになりました。

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

イベントのIDのリストを含むインスタンス化された@interestオブジェクトがすでにあるので、これは私にとってはうまくいきました。もちろん、Railsが利用できる魔法の一部を使用していません。また、「not」でソリューションを機能させることができませんでした。たとえば、;

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

動作しません。 0の結果を返します。しかしこれは:

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

これは機能し、@ interestとの関連付けがないすべてのイベントを返します。

7
ultratoad