web-dev-qa-db-ja.com

Railsのモデルの外部キー関係の定義

Postクラスにpost_idの:foreign_keyを持つCommentクラスがあります。

class Comment < ActiveRecord::Base
  belongs_to :post, :class_name => "Post", :foreign_key => "post_id", :counter_cache => true
  belongs_to :author, :class_name => "User", :foreign_key => "author_id"
end

ただし、CreateCommentsの移行ではデータベースレベルの外部キーは定義されません:

class CreateComments < ActiveRecord::Migration
  def self.up
    create_table :comments do |t|
      t.column "post_id",       :integer,   :default => 0, :null => false
      t.column "author",        :string,    :default => "",   :limit => 25, :null => false
      t.column "author_email",  :string,    :default => "",   :limit => 50, :null => false
      t.column "content",       :text,      :null => false
      t.column "status",        :string,    :default => "",   :limit => 25, :null => false
      t.timestamps
    end
  end

  def self.down
    drop_table :comments
  end
end

代わりに、post_idは単純な整数列です。

つまり、この外部キーの関係は、データベースレベルではなく、Railsの心の中にのみ存在するようです。

これは正しいです?

また、対応するPostモデルは、:foreign_key属性を使用して、コメントとの相互外部キー関係も宣言する必要がありますか、それは省略できますか?

class Post < ActiveRecord::Base
  set_table_name("blog_posts")
  belongs_to :author, :class_name => "User", :foreign_key => 'author_id'
  has_many :comments, :class_name => "Comment",
    :foreign_key => 'post_id', :order => "created_at desc", :dependent => :destroy
  has_many :categorizations
  has_many :categories, :through => :categorizations
  named_scope :recent, :order => "created_at desc", :limit => 5

end
53
pez_dispenser

Railsデフォルトの動作では、モデルの外部キーを保持するために使用される列は、接尾辞_idが追加された関連付けの名前です。:foreign_keyオプションにより、外部キーの名前を直接設定すると、PostCommentモデルクラス間の関連付けは次のようになります。

class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post
end

Commentモデルに:class_name => "Post"は必要ないことに注意してください。 Railsはすでにその情報を持っています。Railsの規約をオーバーライドする必要がある場合にのみ:class_name:foreign_keyを指定する必要があります。

Railsは外部キー関係を維持します。外部キー制約を追加することにより、必要に応じてデータベース層でそれらを強制できます。

75
John Topley