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

Al *_*cks 2 model ruby-on-rails save

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

class Hotel
  belongs_to :user
  has_one    :address
  accepts_nested_attributes_for :address
Run Code Online (Sandbox Code Playgroud)

class Address
  belongs_to :hotel
Run Code Online (Sandbox Code Playgroud)

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

输入表单很简单:

<%= 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 %>
Run Code Online (Sandbox Code Playgroud)

酒店控制器:

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
Run Code Online (Sandbox Code Playgroud)

但是这段代码不起作用.

添加1条酒店 _params:

  private
    def hotel_params
      params.require(:hotel).permit(:title, :stars, :room, :price)
    end
Run Code Online (Sandbox Code Playgroud)

添加2

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

<%= f.fields_for :address do |o| %> 
Run Code Online (Sandbox Code Playgroud)

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

Pav*_*van 6

您正在使用wrong method与该parent.And附加你的孩子也很has_one relation,所以你应该使用build_modelmodel.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
Run Code Online (Sandbox Code Playgroud)

更新

你的hotel_params方法应该是这样的

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