Wenn man derzeit eine Join-Tabelle wie folgt generiert:
rails g migration create_join_table_showroom_user showroom user
die folgende Migration wird erstellt:
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
Wenn Sie diese Migration direkt ausführen, wird eine sehr einfache Join-Tabelle erstellt:
create_table "showrooms_users", id: false, force: :cascade do |t|
t.integer "showroom_id", null: false
t.integer "user_id", null: false
end
Also keine Indizes, keine Fremdschlüssel etc. Entkommentiert man die beiden Zeilen bei der Migration, erhält man nun:
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
Ich würde argumentieren, dass die generierte Migration so aussehen sollte:
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
Wenn man die beiden references
Zeilen auskommentiert, sieht die erzeugte Tabelle so aus:
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"
Warum möchte jemand keine Fremdschlüssel und Indizes in einer Join-Tabelle haben? @rafaelfranca
Ich stimme zu! Ich muss das die ganze Zeit machen. Vielleicht könnten wir dem Generator Optionen hinzufügen, wie zum Beispiel:
rails g migration ... --fk --idx
oder sie standardmäßig einschließen und Optionen zum Deaktivieren haben, wie zum Beispiel:
rails g migration ... --no_fk --no_idx
Ich weiß nicht, die Migrationen verwenden solche Optionen meistens nicht. Sie können den Index bereits mit :index
aktivieren. Also läuft
rails g migration create_join_table_showroom_user showroom:index user:index
Produziert
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
Außerdem können Sie beim Erstellen von Modellen Referenzen verwenden, um einen Index zu erstellen. Wie so:
rails g migration CreatePost title:string user:references:index
Was produziert:
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
Vielleicht wäre es also am besten, etwas zuzulassen wie:
rails g migration create_join_table_showroom_user showroom:references:index user:references:index
Erstellen Sie dies:
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
Und dann würde die Standardeinstellung rails g migration create_join_table_showroom_user showroom user
Folgendes erzeugen:
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 Das ist eine sehr schöne Lösung. :smiley:
Hilfreichster Kommentar
Ich weiß nicht, die Migrationen verwenden solche Optionen meistens nicht. Sie können den Index bereits mit
:index
aktivieren. Also läuftProduziert
Außerdem können Sie beim Erstellen von Modellen Referenzen verwenden, um einen Index zu erstellen. Wie so:
rails g migration CreatePost title:string user:references:index
Was produziert:
Vielleicht wäre es also am besten, etwas zuzulassen wie:
rails g migration create_join_table_showroom_user showroom:references:index user:references:index
Erstellen Sie dies:
Und dann würde die Standardeinstellung
rails g migration create_join_table_showroom_user showroom user
Folgendes erzeugen: