Rails: create_join_tableには、インデックスと外部キー制約を含める必要があります

作成日 2016年01月07日  ·  3コメント  ·  ソース: rails/rails

現在、次のような結合テーブルを生成すると、次のようになります。

rails g migration create_join_table_showroom_user showroom user

次の移行が作成されます。

class CreateJoinTableShowroomUser < ActiveRecord::Migration
  def change
    create_join_table :showrooms, :users do |t|
      # t.index [:showroom_id, :user_id]
      # t.index [:user_id, :showroom_id]
    end
  end
end

この移行を直接実行すると、非常に単純な結合テーブルが作成されます。

create_table "showrooms_users", id: false, force: :cascade do |t|
  t.integer "showroom_id", null: false
  t.integer "user_id",     null: false
end

したがって、インデックスや外部キーなどはありません。移行で2行のコメントを解除すると、次のようになります。

create_table "showrooms_users", id: false, force: :cascade do |t|
  t.integer "showroom_id", null: false
  t.integer "user_id",     null: false
end

add_index "showrooms_users", ["showroom_id", "user_id"], name: "index_showrooms_users_on_showroom_id_and_user_id", using: :btree
add_index "showrooms_users", ["user_id", "showroom_id"], name: "index_showrooms_users_on_user_id_and_showroom_id", using: :btree

生成された移行は次のようになります。

class CreateJoinTableShowroomUser < ActiveRecord::Migration
  def change
    create_join_table :showrooms, :users do |t|
      # t.references :showroom, index: true, null: false, foreign_key: true
      # t.references :user, index: true, null: false, foreign_key: true
      # t.index [:showroom_id, :user_id]
      # t.index [:user_id, :showroom_id]
    end
  end
end

2つのreferences行のコメントを解除すると、生成されるテーブルは次のようになります。

create_table "showrooms_users", id: false, force: :cascade do |t|
  t.integer "showroom_id", null: false
  t.integer "user_id",     null: false
end

add_index "showrooms_users", ["showroom_id"], name: "index_showrooms_users_on_showroom_id", using: :btree
add_index "showrooms_users", ["user_id"], name: "index_showrooms_users_on_user_id", using: :btree

add_foreign_key "showrooms_users", "showrooms"
add_foreign_key "showrooms_users", "users"

なぜ誰かが結合テーブルでそれらの外部キーとインデックスを望まないのでしょうか? @rafaelfranca

activerecord

最も参考になるコメント

私は知りません、移行はほとんどそのようなオプションを使用しません。 :indexを使用して、インデックスをすでに有効にすることができます。 だから走っている

rails g migration create_join_table_showroom_user showroom:index user:index

を生成します

class CreateJoinTableShowroomUser < ActiveRecord::Migration
  def change
    create_join_table :showrooms, :users do |t|
      t.index [:showroom_id, :user_id]
      t.index [:user_id, :showroom_id]
    end
  end
end

また、モデルを作成するときに、参照を使用してインデックスを作成することもできます。 そのようです:

rails g migration CreatePost title:string user:references:index

生成するもの:

class CreatePost < ActiveRecord::Migration
  def change
    create_table :posts do |t|
      t.string :title
      t.references :user, index: true, foreign_key: true
    end
  end
end

したがって、次のようなものを許可するのが最善かもしれません。

rails g migration create_join_table_showroom_user showroom:references:index user:references:index

これを作成する:

class CreateJoinTableShowroomUser < ActiveRecord::Migration
  def change
    create_join_table :showrooms, :users do |t|
      t.references :showroom, index: true, foreign_key: true
      t.references :user, index: true, foreign_key: true
      # t.index [:showroom_id, :user_id]
      # t.index [:user_id, :showroom_id]
    end
  end
end

そして、デフォルトのrails g migration create_join_table_showroom_user showroom userは次のようになります。

class CreateJoinTableShowroomUser < ActiveRecord::Migration
  def change
    create_join_table :showrooms, :users do |t|
      # t.references :showroom, index: true, foreign_key: true
      # t.references :user, index: true, foreign_key: true
      # t.index [:showroom_id, :user_id]
      # t.index [:user_id, :showroom_id]
    end
  end
end

全てのコメント3件

同意します! 私はいつもこれをしなければなりません。 たぶん、次のようなオプションをジェネレータに追加できます。
rails g migration ... --fk --idx
または、デフォルトでそれらを含め、次のようにそれらを無効にするオプションがあります。
rails g migration ... --no_fk --no_idx

私は知りません、移行はほとんどそのようなオプションを使用しません。 :indexを使用して、インデックスをすでに有効にすることができます。 だから走っている

rails g migration create_join_table_showroom_user showroom:index user:index

を生成します

class CreateJoinTableShowroomUser < ActiveRecord::Migration
  def change
    create_join_table :showrooms, :users do |t|
      t.index [:showroom_id, :user_id]
      t.index [:user_id, :showroom_id]
    end
  end
end

また、モデルを作成するときに、参照を使用してインデックスを作成することもできます。 そのようです:

rails g migration CreatePost title:string user:references:index

生成するもの:

class CreatePost < ActiveRecord::Migration
  def change
    create_table :posts do |t|
      t.string :title
      t.references :user, index: true, foreign_key: true
    end
  end
end

したがって、次のようなものを許可するのが最善かもしれません。

rails g migration create_join_table_showroom_user showroom:references:index user:references:index

これを作成する:

class CreateJoinTableShowroomUser < ActiveRecord::Migration
  def change
    create_join_table :showrooms, :users do |t|
      t.references :showroom, index: true, foreign_key: true
      t.references :user, index: true, foreign_key: true
      # t.index [:showroom_id, :user_id]
      # t.index [:user_id, :showroom_id]
    end
  end
end

そして、デフォルトのrails g migration create_join_table_showroom_user showroom userは次のようになります。

class CreateJoinTableShowroomUser < ActiveRecord::Migration
  def change
    create_join_table :showrooms, :users do |t|
      # t.references :showroom, index: true, foreign_key: true
      # t.references :user, index: true, foreign_key: true
      # t.index [:showroom_id, :user_id]
      # t.index [:user_id, :showroom_id]
    end
  end
end

+ 1 @ erullmannこれは非常に優れたソリューションです。 :スマイリー:

このページは役に立ちましたか?
0 / 5 - 0 評価