2011-02-16 42 views
1

我正在開發我的第一個真正的rails項目,並且正在尋找一些專業建議。MySQL和Rails中的外鍵建議

我期待在我的MySQL數據庫四個表(用戶,圖書,評論,標籤)及以下業務規則。

,用戶可以使一本書一個或多個評論,但評論只能屬於一本書。 用戶可以在一本書上放置一個或多個標籤,但標籤只能屬於一本書。

圖形,我凸輪了以下內容:(ASCII藝術永遠不會死)

+---------+    +---------+ 
|   |    |   | 
|   |    |   | 
| User |1   1| Book | 
|   |----- -----|   | 
+---------+  | | +---------+ 
    | 1  | |   | 1 
    |   | |   | 
    |   | |   |    
    | 1,*  | |   | 1,* 
+---------+  | | 1,*+---------+ 
|   |  ---+----|   | 
|   |1,*  | |   | 
| Comment |--------- | Tag | 
|   |    |   | 
+---------+    +---------+ 

我正在尋找如何在Rails的配置我的模型的任何建議。目前,我期待設置:

class Users 
    has_many :tags 
    has_many :comments 
    has_many :tagsBooks, :through=>tags, :class_name => "tags_books" 
    has_many :commentsBooks, :through=>comments, :class_name => "comments_books" 
end 

class Books 
    has_many :tags 
    has_many :comments 
    has_many :tagsUsers, :through=>tags, :class_name => "tags_users" 
    has_many :commentsUsers, :through=>comments, :class_name => "comments_users" 
end 

class Tags 
    belongs_top :users 
    belongs_to :books 
end 

class Comments 
    belongs_top :users 
    belongs_to :books 
end 

我相信「這將有助於在執行的標籤和註釋表的外鍵字段(USER_ID和Books_id) - 這是最終什麼,我需要做的。我希望這將允許我將標籤和評論與用戶和書籍(即books.tags或users.tags)相關聯。

這是正確的嗎?

我很高興,只要外鍵的分貝和Rails執行,以徹底改變設計。

乾杯,

達摩

+0

是不是您可以重複使用它們的標籤的想法?或者,您是否在此上下文中定義了不同的標籤?我會創建標籤和書籍之間的多對多關係。 – xinit 2011-02-16 07:28:43

回答

4

has_manybelongs_to不要在數據庫級別強制執行外鍵約束。他們提供的方法可以讓你建模關係,如果你按照Rails約定使用方法,一切都會好的。如果您想要實際的約束,則需要將其明確添加到數據庫中。 (foreigner寶石可以幫助生成必要的語句)。

儘管如此,許多(如果不是大多數)Rails開發者是舒服的方式處理的Rails應用程序中,而不是數據庫的關係。你的旅費可能會改變。

你的設計看起來像它會與一些修復工作。我會改變camelcased的名字(「tagsBooks」=>「tag_books」),它雖然有效,但會失去你的風格點。該:class_name必須引用一個真正的類,所以你可能想要做的:

has_many :tag_books, :through => :tags, :class_name => "Book" 
has_many :comment_books, :through => :comments, :class_name => "Book" 

那麼你應該能夠做到:

@book = Book.create 
@user.tag_books.create(:book=>@book) 

你會希望通過對has_many Rails的文檔閱讀和belongs_to。添加:依賴=>:(例如)破壞的連接表通常是一個好主意:

has_many :tags, :dependent => :destroy 
6

這不會強制在數據庫外鍵,它們只是整數列。他們只在模型層面提供幫助。 t.references也沒有幫助。要強制執行外鍵,您需要手動創建它們。我通常不喜歡這樣的遷移方法(updown):

execute <<-SQL 
    ALTER TABLE <table_name> 
    ADD CONSTRAINT fk_name 
    FOREIGN KEY (column_name) 
    REFERENCES table_name(id) 
SQL 

這將創建和DB執行外鍵。

0

爲Rails 5的更新,外鍵現在原生支持。您可以在構建器對象上說t.references comment, foreign_key: true,或者在遷移的其他任何地方使用add_reference :books, :comment, foreign_key: true。這些將在Books表上創建一個comment_id,它將在數據庫級別具有外鍵約束。

如果你的表被命名爲比你希望你的外鍵被稱爲其它什麼東西,只使用to_table選項:

t.references :comment, foreign_key: { to_table: :book_comments }

add_reference :books, :comment, foreign_key: { to_table: :book_comments }

這些創建coment_id指向名爲book_comments的表。