1

私はしばらくレールの問題に頭を悩ませてきましたが、私の発見を確認したかったのです。Has_and_belongs_to_many 関係を機能させようとしましたが、2 つのクラス、auctionItem と category を接続できませんでした。まず、問題を解決する前の移行ファイルと 2 つのクラスを次に示します。

移行ファイル:

class AuctionItemsCategories < ActiveRecord::Migration
  def up
    create_table 'auction_items_categories', :id=>false do |t|
      t.reference :auctionItem_id
      t.references :category_id 
    end
  end

  def down
    drop_table 'auction_items_categories'
  end
end

カテゴリー.rb

class Category < ActiveRecord::Base
  has_and_belongs_to_many :auction_items
end

オークションアイテム.rb

class AuctionItem < ActiveRecord::Base
  has_and_belongs_to_many :categories
end

AuctionItemのインスタンスを作成した後、試してみました

auction_item = AuctionItem.last
auction_item.categories

...そして、次のエラーが発生しました:

NoMethodError: undefined method `categories' for #<AuctionItem:0x0000010521b870>

いくつかの調査の後、特定のクラスを has_and_belongs_to_many に追加すると、次のように役立つことがわかりました。

カテゴリ モデル

has_and_belongs_to_many :auction_items , :class_name => 'AuctionItem'

オークションアイテムモデル

has_and_belongs_to_many :categories , :class_name => 'Category'

これで問題が解決し、カテゴリ テーブルにアクセスできるようになりました。続けて、オークション アイテムにカテゴリを追加してみました。

auction_item.categories << category

その後、次のエラーを受け取りました。

SELECT "auction_items".* FROM "auction_items" INNER JOIN "auction_items_categories" ON "auction_items"."id" = "auction_items_categories"."auction_item_id" WHERE "auction_items_categories"."category_id" = 2
SQLite3::SQLException: no such column: auction_items_categories.auction_item_id: SELECT "auction_items".* FROM "auction_items" INNER JOIN "auction_items_categories" ON "auction_items"."id" = "auction_items_categories"."auction_item_id" WHERE "auction_items_categories"."category_id" = 2
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: auction_items_categories.auction_item_id: SELECT "auction_items".* FROM "auction_items" INNER JOIN "auction_items_categories" ON "auction_items"."id" = "auction_items_categories"."auction_item_id" WHERE "auction_items_categories"."category_id" = 2

お気付きのように、クエリは AuctionItem.id ではなく、auction_item.id を取得しようとしています。接続を機能させるには、移行ファイルを次のように変更する必要がありました。

class AuctionItemsCategories < ActiveRecord::Migration
  def up
    create_table 'auction_items_categories', :id=>false do |t|
      t.integer :auction_item_id
      t.integer :category_id 
    end
  end

  def down
    drop_table 'auction_items_categories'
  end
end

長い話/TL DRバージョン:私にとっては、複数の単語でクラスに名前を付け、キャメルケースを使用する場合、アンダースコアがある場合、レールは複数形のクラス名を元の状態に単一化しないようです。たとえば、私のクラス名は AuctionItem で、モデルのオークションアイテムになりました。auctionitem.idを検索するのではなく、検索された sql 呼び出しは、 auction_itemsの単数形バージョンである、auction_item.id でした。なぜオークションアイテム.idを検索しなかったのですか? 将来、複数の単語クラスで関連テーブルを作成する場合、モデル名の単一アンダースコア ID バージョンを使用する必要がありますか?

4

1 に答える 1

1

元の移行は正しくありませんでした。次のようになっているはずです。

class AuctionItemsCategories < ActiveRecord::Migration    
  def up
    create_table 'auction_items_categories', :id => false do |t|
      t.references :auction_item
      t.references :category
    end
  end

  def down
    drop_table 'auction_items_categories'
  end
end

参照を使用する場合は、シンボル化されたモデル名を指定する必要があります。

于 2012-12-14T21:31:42.890 に答える