user:referencesとuser_id:integerを使用してモデルを生成する


176

別のモデルに属するモデルを生成する方法に困惑しています。私の本では、この構文を使用してMicropostをユーザーに関連付けています。

rails generate model Micropost user_id:integer

しかし、http//guides.rubyonrails.org/は次のようにするように言っています:

rails generate model Micropost user:references

これら2つによって生成される移行は異なります。また、前者の場合、レールはそれuser_idが外部キー参照であることをどのようにして知るのuserでしょうか?ありがとう!

回答:


190

移行を実行すると、どちらも同じ列を生成します。Railsコンソールで、これが事実であることがわかります:

:001 > Micropost
=> Micropost(id: integer, user_id: integer, created_at: datetime, updated_at: datetime)

2番目のコマンドはbelongs_to :userMicropostモデルに関係を追加しますが、最初のコマンドは関係を追加しません。この関係が指定されている場合、ActiveRecordは外部キーがuser_id列に保持されていると想定しUser、特定のユーザーをインスタンス化するために名前が付けられたモデルを使用します。

2番目のコマンドも新しいuser_id列にインデックスを追加します。


1
2つのテーブルの参照を含むモデルを生成することは可能ですか
praveenkumar

他のモデル(ユーザー)にhas_manyアソシエーションを追加しないことに注意してください。これも追加したい場合があります。
Sv1

45

Railsはそれuser_idが外部キー参照であることをどのようにして知るのuserですか?

Rails自体user_idは、それが外部キー参照であることを認識していませんuser。最初のコマンドrails generate model Micropost user_id:integerでは、列を追加するだけですが、user_idレールはcolの使用を認識していません。Micropostモデルにラインを手動で配置する必要があります

class Micropost < ActiveRecord::Base
  belongs_to :user
end

class User < ActiveRecord::Base
  has_many :microposts
end

キーワードbelongs_tohas_manyこれらのモデル間の関係を決定し、モデルuser_idへの外部キーとして宣言しUserます。

rails generate model Micropost user:references後者のコマンドはモデルに行belongs_to :userを追加し、Micropostこれにより外部キーとして宣言します。


前の方法を使用して外部キーを宣言するFYIは、モデル/テーブルの関係をRailsに知らせるだけです。データベースは関係について不明です。したがって、ソフトウェアを使用してEER図を生成するMySql Workbenchと、モデル間に関係スレッドが描画されないことがわかります。次の写真のように ここに画像の説明を入力してください

ただし、後者の方法を使用すると、移行ファイルは次のようになります。

def change
    create_table :microposts do |t|
      t.references :user, index: true

      t.timestamps null: false
    end
    add_foreign_key :microposts, :users

これで、外部キーがデータベースレベルで設定されました。適切なEER図を生成できます。 ここに画像の説明を入力してください


1
最新のRailsジェネレーターがadd_foreign_keyアクションを行のオプションforeign_key: trueに置き換えたt.referencesようindex: trueです。だから今t.references :user, foreign_key: trueです。現在foreign_key利用可能なオプションのドキュメントがないので、これは私の仮定にすぎません。
フランクリン・ユウ

ああ、add_referenceアクションに適切な外部キー制約:foreign_key追加するオプションがあります。このオプションは、テーブルを作成するときにも同じようになると思います。
フランクリン・ユウ

ruby dbをどのようにワークベンチにエクスポートしますか?:あなたは多分ここに、この答えることができるstackoverflow.com/questions/42982921/...
Krawalla

たんadd_foreign_key :microposts, :users Railsのための任意の違いを作りますか?
Linus

17

前者については、構成に関する規約。Railsが別のテーブルを参照するときのデフォルト

 belongs_to :something

を探すことですsomething_id

references、またはbelongs_to実際には少し奇妙な前者を書く新しい方法です。

重要なのは、それが外部キーを作成しないことを覚えておくことです。そのためには、次のいずれかを使用して明示的に設定する必要があります。

t.references :something, foreign_key: true
t.belongs_to :something_else, foreign_key: true

または(複数形に注意):

add_foreign_key :table_name, :somethings
add_foreign_key :table_name, :something_elses`

1
参照によって外部キーが作成されないことを言って、どういう意味ですか?user_id:integerを直接使用する最初のコマンドとどう違うのですか?
shailesh 2012

そうではありませんが、:polymorphicオプションを使用している場合を除きます(ほとんどの場合、IMHOはお勧めできません)。ActiveRecordで外部キーを利用したい場合は、foreignerを使用してください。
Krule

1
@Krule add_foreign_keyはActiveRecordになりました。
フランクリン・ユウ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.