2009-05-24 11 views
48

Mam klasę komentarza z: foreign_key z post_id w klasie Post.Definiowanie relacji kluczy obcych dla modeli Railsowych

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 

Ale moja CreateComments migracji nie definiuje się na poziomie bazy danych klucza obcego:

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 

Zamiast post_id jest prosta kolumna Integer.

Wydaje się więc, że ten związek klucza obcego istnieje tylko w umyśle Rails, a nie na poziomie bazy danych.

Czy to prawda?

Czy jest również konieczne, aby odpowiedni model Posta również zadeklarował swoją wzajemną relację klucza obcego z komentarzami za pomocą atrybutu: foreign_key lub czy można go pominąć?

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 
+0

Dzielę się niespodzianką, że Rails nie używa kluczy obcych SQL. Utrudnia to używanie narzędzi nie-szynowych na DB. – Greg

+2

Railsy są zgodne z konwencją, że "WSZYSTKIE logiki biznesowe powinny być zdefiniowane w aplikacji" ... więc używa DB tylko jako "głupiego" magazynu. Bez kluczy obcych, bez procedur składowanych, bez ograniczeń (na przykład obsługiwane w postgresie). EDYCJA: Właśnie znalazłem tę odpowiedź, która mówi to samo - http://stackoverflow.com/questions/8334602/need-to-create-a-foreign-key-when-creating-a-table-on-rails –

+1

https://github.com/matthuhiggins/foreigner – wberry

Odpowiedz

69

szyn domyślne zachowanie jest, że kolumna używana do przechowywania klucza obcego w modelu to nazwa stowarzyszenia z przyrostkiem _id dodanej. Opcja :foreign_key pozwala bezpośrednio ustawić nazwę klucza obcego. Związek między klasach modelowych Post i Comment powinna wyglądać następująco:

class Post < ActiveRecord::Base 
    has_many :comments 
end 

class Comment < ActiveRecord::Base 
    belongs_to :post 
end 

— Należy pamiętać, że nie trzeba :class_name => "Post" w modelu Comment. Railsy już mają te informacje. Powinieneś określać tylko :class_name i :foreign_key, kiedy musisz zastąpić konwencje Railsów.

Masz rację, że Railsy utrzymują dla ciebie relacje klucza obcego. Możesz wymusić je w warstwie bazy danych, jeśli chcesz, dodając ograniczenia klucza obcego.

+0

Ponieważ połączenie foreign_key nie znajduje się na poziomie bazy danych i tylko w szynach. Jeśli rekord zostanie usunięty z wpisu, czy powiązany z nim wiersz w komentarzu zostanie również usunięty? Jest to kolejna korzyść z utrzymywania foreign_key. Czy dostanę tę korzyść? –

+0

Jeśli chcesz usunąć również powiązaną kolumnę. Musisz dodać 'dependent: destroy 'na końcu linii, którą utworzyłeś. – Lavika

Powiązane problemy