在Rails中遇到关联问题

时间:2014-05-08 19:10:15

标签: ruby-on-rails ruby-on-rails-4

我正在创建一个餐馆应用程序,将餐馆列为轨道启动项目。现在,我希望餐厅有一个菜单。

class Restaurant < ActiveRecord::Base
has_one :menu
end

class Menu < ActiveRecord::Base
    belongs_to :restaurant
end

我还通过运行restaurant_id并运行rails generate migration AddRestaurantIDToMenus restaurant_id:integer

在菜单上添加了rake db:migrate的迁移

我现在的问题是如何将新菜单与餐馆相关联?当我创建新的菜单帖子时,它不会自动与餐馆关联。无论如何我可以直接从餐厅的节目页面创建菜单吗?我需要在餐厅控制器区域设置什么?

3 个答案:

答案 0 :(得分:2)

首先,当您迁移属于另一个模型的模型时,不要手动添加外键,而是使用references作为列类型,如下所示

rails g migration AddRestaurantRefToMenus restaurant:references

现在,当您想要创建属于Restaurant实例的菜单时,您可以在控制器中执行以下操作:

@menu = @restaurant.menus.create(some_attribute: some_value, another_attibute: another_value)

绝对阅读the rails guides on associations

答案 1 :(得分:0)

哦,我的......你有很多值得学习的东西......

首先 - 听起来你还处于应用程序的早期阶段,所以除非你有充分的理由保留数据库中已有的数据,否则没有真正的理由来创建一个全新的迁移将restaurant_id添加到您的Menu表格中。只需rake db:migrate VERSION=0,编辑create_menus迁移,然后再次“rake db:migrate”。

就实际创建菜单并将其与餐厅关联而言,您可以通过多种方式进行操作:

餐厅或菜单控制器:

def create_menu
  @restaurant = Restaurant.find(params[id])
  @menu  = Menu.create(:restaurant_id => @restaurant.id, :other_attribute => "something")

  #Or...
  @restaurant.menu = Menu.create(:restaurant_id => @restaurant.id, :other_attribute => "something")

  #Or...
  @menu  = Menu.new(:other_attribute => "something")
  if @menu.save #returns true if saved properly
    @restaurant.menus << @menu
  end
end

答案 2 :(得分:0)

关于如何一起做两件事,你可以在你的餐馆模型中说明

accepts_nested_attributes_for :menu

然后在您的控制器的新功能中,您将拥有类似

的内容
@restaurant  = Restaurant.new
@restaurant.menu = Menu.new

您的新视图现在看起来像

form_for (@restaurant) do |r|
  <%= r... %> #whatever they can set for the restaurant (like a name maybe)
  #

  r.fields_for :menu do |m|
    <%= m... %> #whatever they can set for the menu 
  end

  r.submit "button"
end

最后在控制器中创建看起来像

@restaurant = Restaurant.new(params[:restaurant])
if (@restaurant.save)
  ...
else
  ...
end

您可以通过编辑/更新几乎完全相同的方式(主要区别在于您的餐厅,也许它的菜单已经存在),因此您的编辑看起来像

@restaurant.find(params[:id])

然后在您的更新中它看起来像

@restaurant.find(params[:id])
if @restaurant.update_attributes(params[:id])
  ...
else
  ...
end

希望有助于回答您的一些问题。

P.S。如果您对form_for和不同的输入有疑问,Here是一个很好的起点。