1

私が構築している簡単なフラッシュカードの例として、次のDBがあります。

create_table "card_associations", :force => true do |t|
  t.integer  "card_id"
  t.integer  "deck_id"
end

create_table "cards", :force => true do |t|
  t.string   "question"
  t.string   "answer"
end

create_table "decks", :force => true do |t|
  t.string   "name"
  t.string   "description"
end

すべてのモデルのリレーションシップを通じてhas_manyを設定しました。ここで、デッキIDを指定して、結合テーブルからすべてのカードのリストを返すことができるようにしたいと思います。クエリを実行した場合:

CardAssociation.find_by_deck_id(3).card

これは、deck_idが3の最初のカードを再実行します。しかし、試してみると。

CardAssociation.find_all_by_deck_id(3).card

エラーが発生します

NoMethodError:#の未定義のメソッド `card'

誰かがこれを手伝ってくれますか?非常に単純な間違いをしているような気がします。

助けてくれてありがとう

4

1 に答える 1

1

find_all_ *メソッドは常に配列(空の場合もあります)を返します!

CardAssociation.find_all_by_deck_id(3) # => Array of results
CardAssociation.find_all_by_deck_id(3).first # => first result of the Array or nil if no result

最初にRubyonRailsスタイルガイドを読んでから、Rails3の方法でActiveRecordでオブジェクトを検索することをお勧めします。

CardAssociation.where(:deck_id => 3) # => Array of results
CardAssociation.where(:deck_id => 3).first # => first result of the Array if exists

あなたの場合、スコープはカードモデルに設定することができます:

あなたは次のように述べています。「デッキIDを指定して、参加テーブルからすべてのカードのリストを返すことができるようにしたい

class Card < ActiveRecord::Base
  scope :for_deck, lambda { |deck| joins(:card_associations).where('card_associations.deck_id = ?', deck.try(:id) || deck) }
end

このスコープは、次のように使用できます。

Card.for_deck(deck) # returns an Array of Card objects matching the deck.id

スコープで定義されているように、のパラメーターはオブジェクトまたはdeck_id(整数型)にCard.for_deck(deck)することができます。deck

これがお役に立てば幸いです。

于 2012-11-20T20:04:04.333 に答える