0

通過關聯使用has_many時是否有任何(乾淨)的方式來訪問單個關聯?通過在Rails中從has_many中選擇單個關聯

例如,讓所有配方的成分,我可以這樣寫:

@ingredients = @recipe.ingredients

但是,如果我有一個成分已經選擇了,我希望將數據添加到連接表的配方/成分,我無法弄清楚添加數據的乾淨方式。

我無法訪問使用

ingredient = Ingredient.find(an_id) 

amount = @recipe.ingredient.amount 

什麼是方法的單一成分協會的量選擇存儲在連接表中的單個成分的信息?

+0

所以你找到了你想要的食譜,你已經找到了食譜的配料。你想編輯這些成分之一的屬性嗎?或者你想爲之前選擇的配方添加新的成分嗎?或者是否有另一個您想要填充的成分的聯合表格? – holaSenor

+0

食譜和配料上有一個連接表,用於保存與其相關食譜特定成分有關的信息,即每種成分的含量。 –

回答

-1

我不明白這樣的事情會如何存在。如果您有多個關聯的對象,則需要指定哪一個需要。這不是限制Rails作爲...的限制我不知道,集合論?邏輯? 您可以通過.firstingredient = @recipe.ingredients.first)獲得其中一個關聯對象,但除非您還指定了一個訂單,否則無法確定它會是哪一個。

+0

這很有趣...集合論。它完全在數據庫的限制範圍之內,並且has_many關係對於一個或兩個表都只有一個記錄(在表本身中或只有一個具有匹配的鍵)。很顯然,這不是任何限制。如果你不相信我,那就試試吧。 – holaSenor

0

你可以@ingredient = @recipe.ingredients.first(如果它確實是唯一的一個,不知道你怎麼會知道這是肯定的。)

假設你已經配料選擇,作爲一個變量,你可以將它們像任何其他ActiveRecord對象。

@ingredient = @recipe.ingredients.first 
@ingredient.amount = 15 #or @ingredient.amount = params[:amount] (if you get the new value from POST) 
@ingredient.unit = "Ounces" 
@ingredient.save 

如果你只是想檢索每個成分的配方的屬性,並做一些與他們一樣,在你可以試試這個視圖某些HTML標記顯示它們。

@ingredients = @recipe.ingredients 
    @ingredients.each do |ingr| 
    info = %w[amount, brand, id, recipe_id , unit].map do |attr| 
     ingr.send(attr) 
    end 

在每個內環陣列「信息」的端部將是一種成分的所有屬性。(假設將它們包含在信息陣列)

這是一個表,你可能的一個例子使用存儲的關聯,它應與軌道:through => :recipe_ingedient方法工作:

CREATE TABLE `recipe_ingredient` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `recipe_id` int(11) NOT NULL, 
    `ingedient_id` int(11) NOT NULL, 
    `created_at` datetime DEFAULT NULL, 
    `updated_at` datetime DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci$$ 
+0

你想如何訪問@ recipe.ingeredient?這將拋出一個NameError「未定義的方法'成分'爲#」 –

+0

我理解這裏的邏輯在背後選擇一種成分,但我想知道什麼是最有效的方式來存儲數據在食譜之間的連接表和成分。 –

+0

recipe_id,ingredient_id – holaSenor

0

連接表是對你很重要,所以它應該有一個名字。 你可以稱它爲recipe_ingredient,但是真實的名字有助於不會在精神上混淆這些事物。 (並且它幫助我們討論該問題)

鑑於連接表被稱爲例如slot

class Recipe 
    has_many :slots 
    has_many :ingredients, :through => :slots 
    .. 
class Slot 
    belongs_to :recipe 
    belongs_to :ingredient 
    ... 

通過調用

@slot = @recipe.slots.where(:ingredients_id => @ingredient).first 
@slot.amount = 20 

對於額外的效率,並確保每個組合只存在一個時間內得到規定的插槽,你可以定義一個獨特的複合索引插槽在兩個recipe_id跨越和ingredient_id

1

選項:select在這種情況下非常有用。例如

class Recipe 
    has_many :ingredients, through: ingredients_recipes, select: "ingredinets.*, ingredients_recipes.some_additional_column as some_additional_column" 
    .... 

然後就叫

Recipe.first.ingredients.first.some_additional_column # => profit! 

您可以在示波器使用它。