web-dev-qa-db-ja.com

Rails has_and_belongs_to_many migration

Has_and_belongs_to_many関係を実行したい2つのモデルrestaurantuserがあります。

モデルファイルに既に入り、has_and_belongs_to_many :restaurantsおよびhas_and_belongs_to_many :users

この時点で、Rails 3:

Rails generate migration ....

しかし、私が試したすべてが失敗するようです。これはRailsが初めてなので、本当に簡単なものだと思います。

113
dbslone

アルファベット順で、restaurant_iduser_id(主キーなし)のみを含む個別の結合テーブルを追加する必要があります。

最初に移行を実行してから、生成された移行ファイルを編集します。

レール3

Rails g migration create_restaurants_users_table

レール4

Rails g migration create_restaurants_users

レール5

Rails g migration CreateJoinTableRestaurantUser restaurants users

docs から:

JoinTableが名前の一部である場合、結合テーブルを生成するジェネレーターもあります。


移行ファイル(:id => falseに注意してください。主キーの作成を妨げるものです):

レール3

class CreateRestaurantsUsers < ActiveRecord::Migration
  def self.up
    create_table :restaurants_users, :id => false do |t|
        t.references :restaurant
        t.references :user
    end
    add_index :restaurants_users, [:restaurant_id, :user_id]
    add_index :restaurants_users, :user_id
  end

  def self.down
    drop_table :restaurants_users
  end
end

レール4

class CreateRestaurantsUsers < ActiveRecord::Migration
  def change
    create_table :restaurants_users, id: false do |t|
      t.belongs_to :restaurant
      t.belongs_to :user
    end
  end
end

t.belongs_toは必要なインデックスを自動的に作成します。 def changeは、アップ/ダウンの必要なしに、フォワードまたはロールバック移行を自動検出します。

レール5

create_join_table :restaurants, :users do |t|
  t.index [:restaurant_id, :user_id]
end

注:table_nameという名前のcreate_join_tableにパラメーターとして渡すことができるカスタムテーブル名のオプションもあります。 docs から

デフォルトでは、結合テーブルの名前は、create_join_tableに提供された最初の2つの引数の和集合からアルファベット順になります。テーブルの名前をカスタマイズするには、:table_nameオプションを提供します。

242
Dex

ここでの回答はかなり古いものです。 Rails 4.0.2、現在の移行ではcreate_join_table

移行を作成するには、次を実行します。

Rails g migration CreateJoinTableRestaurantsUsers restaurant user

これにより、以下が生成されます。

class CreateJoinTableRestaurantsUsers < ActiveRecord::Migration
  def change
    create_join_table :restaurants, :users do |t|
      # t.index [:restaurant_id, :user_id]
      # t.index [:user_id, :restaurant_id]
    end
  end
end

これらの列のインデックスを作成する場合は、それぞれの行のコメントを外してください。

30
Jan Klimo

結合テーブルを作成するとき、移行名/クラスで2つのテーブルをアルファベット順でリストする必要があるという要件に注意してください。モデル名が似ている場合、これは簡単に噛みつきます。 「abc」および「abb」。実行する場合

Rails g migration create_abc_abb_table

あなたの関係はnot期待通りに機能します。使用する必要があります

Rails g migration create_abb_abc_table

代わりに。

24
shacker

HABTM関係の場合、結合テーブルを作成する必要があります。結合テーブルのみがあり、そのテーブルにはid列を含めることはできません。この移行を試してください。

def self.up
  create_table :restaurants_users, :id => false do |t|
    t.integer :restaurant_id
    t.integer :user_id
  end
end

def self.down
  drop_table :restaurants_users
end

確認する必要があります この関係Railsガイドチュートリアル

6
Mohit Jain