Ruby on Rails从一个表单中保存两个表

时间:2014-07-14 22:14:25

标签: ruby-on-rails model save

我有两个型号酒店和地址。 关系是:

class Hotel
  belongs_to :user
  has_one    :address
  accepts_nested_attributes_for :address

class Address
  belongs_to :hotel

我需要从一个表单中保存在酒店表格和地址表格中。

输入表单很简单:

<%= form_for(@hotel) do |f| %>

  <%= f.text_field :title %>
  ......other hotel fields......

  <%= f.fields_for :address do |o| %>
    <%= o.text_field :country %>
    ......other address fields......

  <% end %>
<% end %>

酒店管制员:

class HotelsController < ApplicationController
  def new
    @hotel = Hotel.new
  end

  def create
    @hotel = current_user.hotels.build(hotel_params)
    address = @hotel.address.build
    if @hotel.save      
      flash[:success] = "Hotel created!"
      redirect_to @hotel
    else
      render 'new'      
    end    
  end

但是这段代码不起作用。

添加1 Hotel_params:

  private
    def hotel_params
      params.require(:hotel).permit(:title, :stars, :room, :price)
    end

ADD 2

主要问题是我不知道如何正确渲染表单。这个^^^表单甚至不包括地址字段(国家,城市等)。但如果在行

<%= f.fields_for :address do |o| %> 

我更改:地址到:酒店,我在表单中获取地址字段,但当然没有任何保存:在这种情况下的地址表。我不明白从1个表格中保存2个表格的原则,我很抱歉,我是Rails的新手......

3 个答案:

答案 0 :(得分:6)

您正在使用 wrong method 将您的孩子与父母一同追加。而且 has_one relation ,所以您应该使用 build_model 不是 model.build 。您的newcreate方法应该是这样的

class HotelsController < ApplicationController
  def new
    @hotel = Hotel.new
    @hotel.build_address #here
  end

  def create
    @hotel = current_user.hotels.build(hotel_params)

    if @hotel.save      
      flash[:success] = "Hotel created!"
      redirect_to @hotel
    else
      render 'new'      
    end    
  end

<强>更新

您的hotel_params方法应如下所示

def hotel_params
   params.require(:hotel).permit(:title, :stars, :room, :price,address_attributes: [:country,:state,:city,:street])
end

答案 1 :(得分:2)

您不应该再次建立地址

class HotelsController < ApplicationController
  def new
    @hotel = Hotel.new
  end

  def create
    @hotel = current_user.hotels.build(hotel_params)
    # address = @hotel.address.build 
    # the previous line should not be used
    if @hotel.save      
      flash[:success] = "Hotel created!"
      redirect_to @hotel
    else
      render 'new'      
    end    
  end

答案 2 :(得分:2)

这里的底线是您需要正确使用f.fields_for方法。

-

<强>控制器

要使方法起作用,您需要做几件事。首先,您需要构建关联对象,然后您需要能够以正确的方式将数据传递给模型:

#app/models/hotel.rb
Class Hotel < ActiveRecord::Base
   has_one :address
   accepts_nested_attributes_for :address
end

#app/controllers/hotels_controller.rb
Class HotelsController < ApplicationController
    def new
       @hotel = Hotel.new
       @hotel.build_address #-> build_singular for singular assoc. plural.build for plural
    end

    def create
        @hotel = Hotel.new(hotel_params)
        @hotel.save
    end

    private

    def hotel_params
        params.require(:hotel).permit(:title, :stars, :room, :price, address_attributes: [:each, :address, :attribute])
    end
end

这应该适合你。

-

<强>表格

您表单的一些提示 - 如果您正在加载表单&amp;没有看到f.fields_for区块显示,它基本上意味着您未正确设置ActiveRecord Model(在new操作中)

我上面写的(与Pavan写的非常类似)应该让它为你工作