-1

我试图弄清楚如何获取一个名为“meal”的对象的当前实例来创建一个属于它的食物对象。

它在控制台中工作......它很简单,就像这样:

user = User.first
user.meal.first.meal_foods.create

一个用户可以吃很多餐,每餐可以有很多餐食。

对我来说,这里的挑战是食物控制器在创建我的餐食时的创建动作。

(我在这里使用 STI,因此使用“foods”控制器和“meal_food”名称)

目前,创建操作如下所示:

 @food = current_user.meal.meal_foods.build 

我也试过这个,因为复数对象名称的东西

 @food = current_user.meal.meal_food.build 

这是它给两者的错误

undefined method `meal_foods' for [#<Meal id: 17, user_id: 1, meal_name: "Meal">]:ActiveRecord::Relation

更新:

我在这里特别遇到的问题是选择正确的餐点来创建餐食。

在控制台中,我可以选择第一个,这很好。但是在食品控制器中,我需要选择正确的餐点来创建餐食。

编写餐食.first 将为该用户选择第一餐。如果我想从 5 餐中选择第 3 餐,我需要想办法获取该餐的 ID。

我刚刚试过这个:

<%= link_to "new food", foods_path(id: meal.id), method: :create %>

将meal.id 作为可在foods_controller 中使用的参数传入。然后在 foods_controller 中我做了:

@meal_food = current_user.meals.find_by_id(params[:id]).meal_foods.build 

看起来它正在提交,因为页面重新加载了成功消息,但是没有创建 meal_food,所以它只是没有显示。

我检查了控制台,并没有为这个用户的第一餐创建新的食物。


好的,我意识到我上面写的 link_to 创建了这个 url:

foods?id=29

并且我用来检索这个 id 的方法不起作用,因为 params[:id] 正在寻找一个路径 id,而不是这个 url id。

提前致谢!


模型:

class Meal < ActiveRecord::Base
  before_save :sanitize
  has_and_belongs_to_many :meal_foods
  attr_accessible :meal_name

  def sanitize
    self.meal_name = "Meal"
  end
end 


class Food < ActiveRecord::Base
  attr_accessible :brand, :carbs, :fat, :name, :protien, :type

end   

class MealFood < Food
  has_and_belongs_to_many :meals
end 

class User < ActiveRecord::Base

  has_many :meal, dependent: :destroy
  has_many :custom_foods, dependent: :destroy 

控制器:

class FoodsController < ApplicationController
  #functions
  def create

    #this is where I need to grab the correct meal, and then create a meal_food for it...

    if @meal_food.save!
      flash[:success] = "Food created successfully!"
      redirect_to meal_path(current_user.id)
    else
      flash[:error] = "Food couldn't be created."
      redirect_to meal_path(current_user.id)
    end
 end
end 

部分:

这是重复显示每餐的餐食部分。它有 link_to 用于创建属于它所在的餐点的餐点。

<tr>
  <thead class=meal-thead>
   <td class=meal-thead-name> <%= meal.meal_name %> </td>
     <th> </th>
     <th> </th>
     <th> </th>
     <th> </th>
     <th> <%= link_to "x", meal_path(meal.id), method: :delete %> </th>
  </thead>

  <tbody class=meal-tbody>

  <%# get reference to current meal and its foods %>
  <%= render meal.meal_foods %>

  <td class=remove-td-center> <%= link_to "new food", foods_path, method: :create %> </td> 
 </tbody>    
</tr> 
4

2 回答 2

1

有时你说 User.meal.meal_foods,有时你说 User.meal.first.meal_foods。User.meal 是一个膳食数组,因此从控制台 User.meal.first.meal_foods 可以工作,并且在您的代码中 User.meal.meal_foods 不会给您任何方法错误。此外,您应该在代码中使用复数餐点,并将 has_many 餐点替换为 has_many 餐点。

于 2013-04-06T16:25:45.613 回答
1

几件事:

  1. "has_many :meal,dependent: :destroy" 应该是 "has_many :meals,dependent: :destroy" has_many 关联名称是复数形式。如果您只需要一个,请改用 has_one。
  2. 这行是错误的:@food = current_user.meal.meal_food.build,因为餐是 has_many,所以你需要一个“第一”。另外,它返回的不是食物,而是meal_food,所以你应该这样说,否则你会迷惑自己:

    @meal_food = current_user.meal.first.meal_food.build

我突然想到 MealFood => 一个更好的名字应该是 Serving。然后你的饭菜可以有_many servings,每份可以有一个食物。没有错误,只是更容易理解。然后你会有以下代码。请注意,我没有看到 STI 对食物的意义——将所吃食物的数量简单地放在份量表中更有意义,那么你根本不需要 STI。

  class Meal < ActiveRecord::Base
    before_save :sanitize
    has_many :servings
    has_many :foods, :through => :servings
    attr_accessible :meal_name

    def sanitize
      self.meal_name = "Meal"
    end
  end 


  class Food < ActiveRecord::Base
    attr_accessible :brand, :carbs, :fat, :name, :protein, :type
    has_many :servings, :inverse_of => :food
  end   

  class Serving < ActiveRecord::Base
    attr_accessible :amount
    has_many :foods
    has_many :meals
  end 

  class User < ActiveRecord::Base
    has_many :meals, dependent: :destroy
  end

高温高压

于 2013-04-06T16:36:06.757 回答