尝试从父对象控制器创建子类对象



我想弄清楚如何抓住一个名为"meal"的对象的当前实例来创建一个属于它的食物对象。

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

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

用户可以有很多餐,每个餐可以有很多meal_foods。

对我来说,这里的挑战是在创建我的meals_food的食品控制器的创建操作。

(我在这里使用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

更新:

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

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

写餐。首先为用户选择第一顿饭。如果我想从5顿饭中选择第三顿,我需要找到一种方法来获取那顿饭的id。

我已经试过了:

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

把饭传进去。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> 

几点:

  1. "has_many:meal, dependent::destroy"应该是"has_many:meals, dependent::destroy"Has_many关联名称是复数形式的。如果你只想要一个,请使用has_one。
  2. 这一行是错误的:@food = current_user.meal.meal_food。Build,因为meal是一个has_many,所以你需要一个"first"。此外,它不返回一个食物,而是一个meal_food,所以你应该这样说,否则你会混淆自己:

    @meal_food = current_user.meal.first.meal_food。构建

我想到,对于MealFood =>,一个更好的名字应该是服务。然后你的一餐可以有很多份,每份可以有一种食物。不是错误,只是更容易理解。然后您将得到以下代码。请注意,我没有看到食物的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

HTH

有时你说User.meal。meal_foods,有时你会说user。meal。first。meal_foods。用户。meal是一个膳食数组,因此来自控制台User.meal.first。meal_foods工作,并且在您的代码中User.meal。Meal_foods没有方法错误。此外,您应该在代码中使用复数形式的膳食,并将has_many meal替换为has_many meals。

最新更新