web-dev-qa-db-fra.com

Définition des relations de clé étrangère pour les modèles Rails

J'ai une classe Comment avec un: foreign_key de post_id dans la classe Post.

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

Mais ma migration CreateComments ne définit pas de clé étrangère au niveau de la base de données:

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

Au lieu de cela, post_id est une simple colonne entière.

Il semble donc que cette relation de clé étrangère n'existe que dans l'esprit de Rails, pas au niveau de la base de données.

Est-ce correct?

De plus, est-il nécessaire que le modèle Post correspondant déclare également sa relation de clé étrangère réciproque avec les commentaires en utilisant l'attribut: foreign_key ou cela pourrait-il être omis?

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

Le comportement par défaut Rails est que la colonne utilisée pour contenir la clé étrangère sur un modèle est le nom de l'association avec le suffixe _id Ajouté. Le :foreign_key L'option vous permet de définir directement le nom de la clé étrangère. Les associations entre vos classes de modèle Post et Comment doivent ressembler à ceci:

class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post
end

—Notez que vous n'avez pas besoin de :class_name => "Post" Dans votre modèle Comment. Rails possède déjà ces informations. Vous ne devez spécifier :class_name Et :foreign_key Que lorsque vous devez remplacer les conventions Rails.

Vous avez raison: Rails conserve les relations de clé étrangère pour vous. Vous pouvez les appliquer dans la couche de base de données si vous le souhaitez en ajoutant des contraintes de clé étrangère.

75
John Topley