2016-04-24 55 views
0

我總是覺得這個概念有問題。我得到了協會允許你做的事情,我似乎無法分辨協會是否設置在應用程序中。鋼軌協會如何設置?

例如,我爲line_items生成了一個腳手架,在我運行遷移之前,我在正確的模型中設置了belongs_to和has_many方法,然後運行我的遷移。

運行我的遷移後,我看看我的模式,我無法確定是否設置了任何關聯。對我來說,它看起來並不像它,因爲我沒有看到架構設置任何關係。

has_many和belongs_to方法是否設置了關聯?或者他們在那裏讓開發人員閱讀代碼以瞭解關係?

如果關聯設置正確,我的模式會如何查看?我是否需要回滾最後一次遷移幷包含正確的索引?

create_table "carts", force: :cascade do |t| 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    end 

    create_table "line_items", force: :cascade do |t| 
    t.integer "product_id" 
    t.integer "cart_id" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    end 

    create_table "products", force: :cascade do |t| 
    t.string "title" 
    t.text  "description" 
    t.string "image_url" 
    t.decimal "price",  precision: 8, scale: 2 
    t.datetime "created_at",       null: false 
    t.datetime "updated_at",       null: false 
    end 
+0

cart_id是您的關聯。這是說你的產品「有很多」的購物車。因爲每個購物車都可以通過將cart_id設置爲產品ID來擁有許多產品。 – agustaf

回答

1

「關聯」是一個軌道的概念,由has_manybelongs_to ...實現,所以這些行不僅僅是爲了文檔,他們創建了關聯。

你必須在line_itemsproduct_idcart_id,我以爲

class LineItem 
    belongs_to :cart 
    belongs_to :product 
    ... 
end 

class Product 
    has_many :line_items 
    ... 
end 

class Cart 
    has_many :line_items 
    ... 
end 

has_manybelongs_to設置護欄協會和手段軌現在知道有關聯...

my_line_item.cart 
my_line_item.product 
my_cart.line_items 
my_product.line_items 

如果你沒有has_manybelongs_to它不會工作。

關聯需要列card_idproduct_id才能工作,因爲它們是記錄鏈接的方式,需要存在於關係的belongs_to一側。他們不必被稱爲他們被稱爲,但如果你沒有專門在belongs_tohas_many中使用不同的foreign_key名稱,那麼這些字段名稱是軌道所期望的。最好使用預期的名稱......「慣例優於配置」是偏好。

如果你沒有決定調用外鍵vegetable_id代替product_id這很好,但後來你定義的關聯作爲

class LineItem 
    belongs_to :product, foreign_key: :vegetable_id 

class Product 
    has_many :line_items, foreign_key: :vegetable_id 

你可以去一個額外的步驟並有...

class Cart 
    has_many :line_items 
    has_many :products, through: :line_items 
    ... 
end 

這自動神奇地給你的阿比可以做..

my_cart.products 

由於rails知道如何構建SQL命令以通過line_items獲取購物車的所有產品。

因爲您需要belongs_to表中的外鍵,所以您在創建表時需要指定該外鍵。

create_table :line_items do |t| 
    t.integer :product_id 

有一個名爲references是helper_method(也別名爲belongs_to),基本上做同樣的事情...創建:product_id場...

create_table :line_items do |t| 
    t.belongs_to :product 

create_table :line_items do |t| 
    t.references :product 

以上三個版本基本上做同樣的事情...他們創建整數列:product_id

您還可以在:product_id字段中編制索引以提高檢索性能,因此您會偶爾看到index: true,但這不是必需的。

+0

非常感謝這個詳細的答案。當我看到關聯關係的導軌指南時,我發現其中的示例顯示了設置關係的遷移文件,因此我不確定這是否僅僅是爲了說明has_many發生了什麼,以及belongs_to,或者如果您需要在遷移文件中包含類似這樣的內容,請參閱create_table:line_items do | t | t.belongs_to:products,index:true' – adamscott

+0

我在回答中增加了一些信息來解釋't.belongs_to'的含義,希望有所幫助。 – SteveTurczyn

+0

絕對有幫助。感謝您抽出時間史蒂夫。對此,我真的非常感激 – adamscott

2

通過模式來判斷關聯是否正確設置非常簡單。基本上型號有belongs_to應該有相應的表,其中包含foreign_id。例如,在您發佈的架構中,很容易看到lineItem屬於'Product'和Cart,因爲它具有cart_idproduct_id(兩個外部ID)。

activerecord不是黑魔法,全部has_manybelongs_to do只是動態地向模型類添加一個方法,它將查詢轉換爲原始的sql,並將結果映射到ruby對象。但是,您有責任正確設置數據庫表。因爲畢竟,activerecord使用SQL來查詢遵循rails約定的數據。

更新

我想你的意思是輔助方法,在遷移文件,如

t.belongs_to product, index: true, foreign_key: true 

這行代碼也不是一個黑色的魔法,它是一個輔助方法,軌道爲讓你的生活更輕鬆。這相當於做了三件簡單的事情來創建你的數據庫表。

  1. 創建一個foreign_id取決於你的輸入,在上面的例子中,這將是product_id。相當於t.integer product_id
  2. foreign_id上添加一個索引,因爲通常使用foreign_id查詢相關數據很多,添加索引會提高效率。相當於add_index "xxx", ["product_id"], name: "index_xxxs_on_product_id"
  3. 最後foreign_key: true將爲您的foreign_id設置數據庫約束,這樣如果您的子表中仍有一行與父表中的一行相關,則父表中的行不會被意外刪除。這相當於add_foreign_key :xxxs, :products

這樣一個結論,使用add_foreign_key :articles, :authors不會讓任何事情看在你的模式特殊,因爲ActiveRecord只是一個翻譯,使您的生活更輕鬆,當你處理SQL數據庫,它只能做SQL數據庫可以做的事情,沒有什麼特別的。數據庫中關聯的想法只是將foreign_id保存在一個表中,以便您可以使用foreign_id查詢另一個表中的相關數據。

+0

我的答案的第一部分是我理解的,而且這個答案設置得恰到好處。然而,你的答案的第二部分是我被絆倒的地方,以及這個問題起源於何處。根據您在我的模式中看到的內容,是否設置了關聯關係?因爲當我查看關聯的導軌指南時,似乎需要在遷移文件中明確定義關係。但是,當我查看rails的教程時,他們似乎沒有在遷移中定義它們。所以我想知道如果我有這個配置正確。 – adamscott

+0

雅我想你正在談論的一些助手方法軌道爲您提供的遷移文件。比如你可以做't.belongs_to:product,foreign_key:true'。這實際上也不是魔術,它相當於't.integer「product_id」'然後'add_index「xxxx」,[「product_id」],名稱:「index_xxxx_on_product_id」'然後在數據庫中添加一個外部id約束依賴於你正在使用哪個sql數據庫 –

+0

任何看起來像Rails的東西只是一個方便的工具,他們提供了一個方便的工具,通過遵循它們的約定來讓你的生活更輕鬆。但是你絕對可以從頭開始,就像你會做什麼而不使用activerecord一樣。 ''ActiveRecord'就像翻譯器一樣讓你儘可能少地處理原始sql,但它無法做到SQL無法做到的任何事情。 –