0

使用 has_many through 关联时,是否有任何(干净的)方法可以访问单个关联?

例如,要获取食谱的所有成分,我可以这样写:

@ingredients = @recipe.ingredients

但是,如果我已经选择了一种成分,并且我想将数据添加到配方/成分的连接表中,我无法找出添加数据的干净方法。

我无法使用访问单一成分协会的数量

ingredient = Ingredient.find(an_id)  

amount = @recipe.ingredient.amount

选择存储在连接表中的单个成分信息的方法是什么?

4

4 回答 4

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!

你也可以在你的范围内使用它。

于 2012-06-26T23:42:54.220 回答
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

为了提高效率并确保每个组合只存在一次,您可以为 slot 定义一个唯一的复合索引以跨越 recipe_id 和 ingredients_id

于 2012-06-26T21:42:18.600 回答
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

在每个内部循环的末尾,数组“信息”将是一种成分的所有属性。(假设您将它们包含在信息数组中)

这是您可能用于存储关联的表的示例,它应该与 rails: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$$
于 2012-06-25T17:14:24.827 回答
-1

我不明白这样的事情怎么可能存在。如果您有许多关联对象,则需要指定想要的对象。这与其说是 Rails 的限制,不如说是……我不知道,集合论?逻辑?.first您可以使用( )获取关联对象之一ingredient = @recipe.ingredients.first,但除非您还指定了顺序,否则无法确定它将是哪一个。

于 2012-06-25T17:04:36.133 回答