web-dev-qa-db-ja.com

Railsモデル、多くに属しています

モデルの1つを複数のモデルに関連付ける方法を理解するのに苦労しています。

現在のように、私は持っています:

class ModelA < ActiveRecord::Base
  has_many :model_b
end

class ModelB < ActiveRecord::Base
  belongs_to :model_a
end

ただし... ModelBは、ModelAの1つのインスタンスだけでなく、3つのインスタンスにも属している必要があります。 has_many:throughがあることは知っていますが、この場合どのように機能するかわかりません。 ModelAのすべてのインスタンスには、常にModelBのインスタンスが3つあります。ただし、前述のように、ModelBはModelAの複数のインスタンスに属することができます。

24
ardavis

Railsでの多対多の関係はbelongs_toを使用しないでください。代わりに、いくつかのオプションのいずれかを使用する必要があります。最初のオプションはhas_and_belongs_to_manyです。

# app/models/category.rb
class Category < ActiveRecord::Base
  has_and_belongs_to_many :items
end

# app/models/item.rb
class Item < ActiveRecord::Base
  has_and_belongs_to_many :categories
end

そして、次のような移行で、データベースに追加の結合テーブルを追加する必要があります。

class AddCategoriesItems < ActiveRecord::Migration
  def self.up
    create_table :categories_items, :id => false do |t|
      t.integer :category_id
      t.integer :item_id
    end
  end

  def self.down
    drop_table :categories_items
  end
end

結合テーブルの名前が他の2つのテーブルの名前の組み合わせであることがわかります。テーブルは上記のようにアルファベット順に記載する必要があり、:id => falseはそこに存在する必要があります。これは、このテーブルに主キーが必要ないためです。 Rails関連付けを解除します。

関係自体に関する情報を保存する必要がある場合は、has_many :throughと呼ばれる別のより複雑な方法もあります。私は両方の方法を実行する方法とそれぞれをいつ使用するかを詳細に説明する記事全体を書きました:

Railsの基本的な多対多の関連付け

これがお役に立てば幸いです。他にご不明な点がございましたら、お問い合わせください。

48
Jaime Bellmyer

これは@Jaime Bellmyerが使用したものです

# app/models/category.rb
class Category < ActiveRecord::Base
  has_and_belongs_to_many :items
end

# app/models/item.rb
class Item < ActiveRecord::Base
  has_and_belongs_to_many :categories
end

これを使用することをお勧めします

# app/models/category.rb
class Category < ActiveRecord::Base
  has_many :category_items
  has_many :items, :through => :category_items
end

# app/models/item.rb
class Item < ActiveRecord::Base
  has_many :category_items
  has_many :categories, :through => :category_items
end

# app/models/category_items.rb
class CategoryItems < ActiveRecord::Base
  belongs_to :category
  belongs_to :items
end

これを使用すると、カテゴリとアイテムの処理をより詳細に制御できる結合モデルが作成されます。しかし、@ Jaimeが提案したものを使用すると、結合テーブルのみが存在し、モデルは存在しないため、制御できなくなります。

31
Rohit