0

同じRailsプロジェクトで2台の異なるコンピューターでSQLite3とMySQLを使用しています。schema.rbすべての移行を実行したときに生成されるものは、両方の環境で異なって見えることに気付きました。SQLite3環境で移行を実行すると、次のステートメントがファイルから削除さschema.rbます。

add_index "places", ["user_id"], :name => "places_user_id_fk"
add_foreign_key "places", "users", :name => "places_user_id_fk"

とで移行を拡張する外国人の宝石を使用していることに注意してください。add_foreign_keyremove_foreign_key

問題に関連する移行とモデルは次のとおりです。

# 20130123004056_create_places.rb
class CreatePlaces < ActiveRecord::Migration
  def change
    create_table :places do |t|
      t.string :name
      t.string :location
      t.integer :user_id
      t.timestamps
    end
  end
end

..。

# 20130123234250_add_foreign_key.rb
class AddForeignKey < ActiveRecord::Migration
  def change
    add_foreign_key(:places, :users)
  end
end

..。

# user.rb
class User < ActiveRecord::Base
  has_many :places
end

..。

# place.rb
class Place < ActiveRecord::Base
  belongs_to :user    
end

質問: SQLite3とMySQLの両方がそれを処理できる方法で、usersそれらの間の関係をどのように定義できますか?places

4

1 に答える 1

0

foreigner READMEには明確に記載されています

次のアダプターがサポートされています。

  • sqlite (外部キーメソッドは何もしません)

したがって、SQLiteデータベースでは、外部キー制約がサポートされていないため、foreigner外部キー制約が設定されていません。がSQLiteデータベースから生成される場合db/schema.rb、これが外部キーが指定されていない理由です。

Rails Guide on Migrationsは、外部キーについてかなり言及しています

データベースに固有のタスクを実行する必要がある場合(たとえば、外部キー制約を作成する場合)、このexecuteメソッドを使用すると、任意のSQLを実行できます。

外部キーを追加/削除する方法の例もあります。

Railsを最初に使い始めたときに使用foreignerしたので、自分Gemfileとどちらかからドロップすることをお勧めします

  1. 外部キーはまったく使用しないでください。ActiveRecordアソシエーションでカスケードを指定するだけです
  2. execute上記のリンクされた例で説明されている移行方法を使用します(そして、方法に何を入れても、すべての異なるRDBMSがサポートしていることを確認してくださいexecute
  3. 外部キーの使用を主張する場合は、開発中のSQLiteの使用を中止してください。とにかく本番環境でSQLiteを使用することはなく、他のマシンですでにより優れたRDMS(MySQL、探している外部キーサポートがあるという意味で「より優れている」)を使用しています。

コメントで指摘したように、SQLiteは、テーブルの作成後に外部キーを追加するためのサポートが不足しています。Railsでの将来の移行では追加できません。個人的には、選択肢1または3を使用することをお勧めします。executeこれは、他のRDMSでも同じ最終結果が得られる一方で、SQLiteの制限を満たす移行のコマンドを使用してソリューションを作成することがより困難になるためです。

于 2013-01-25T15:15:40.853 に答える