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
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.