使用Formtastic为一个用户创建多个地址

时间:2016-09-23 08:49:24

标签: ruby-on-rails nested-attributes ruby-on-rails-5 formtastic

我目前在Rails 5应用程序中进行了以下设置:

class User < ApplicationRecord
  has_many :addresses
  accepts_nested_attributes_for :addresses
end

class Address < ApplicationRecord
  belongs_to :user
end

相应的控制器如下所示:

class UsersController < ApplicationController
  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)

    if @user.save
      redirect_to users_path
    else
      render 'new', notice: "User could not be created"
    end
  end

  private

  def user_params
    params.require(:user).permit(
      :first_name, :last_name, :email, ...
    )
  end
end

每个用户应该有多个Addresses(例如,用于计费和发货),我需要在用户创建期间设置。表格(由formtastic制作)看起来像这样(采用):

= semantic_form_for @user do |user|
  = user.input :first_name
  = user.semantic_fields_for Address.new do |shipping_address|
    = shipping_address.input :city
    = shipping_address.input :usage,
      as: :hidden,
      input_html: { value: 'shipping' }
  = user.semantic_fields_for Address.new do |billing_address|
    = billing_address.input :city
    = billing_address.input :usage,
      as: :hidden,
      input_html: { value: 'billing' }

问题是,只有后一个地址存在于sites参数中,因此只会创建一个。

如何为同一用户创建多个地址?

1 个答案:

答案 0 :(得分:0)

要创建嵌套记录,您应该对记录进行种子处理并将关联传递给fields_for

例如你会这样做:

class UsersController < ApplicationController
  # ...
  def new
    @user = User.new
    # if we skipped this step there would be no address inputs on the form.
    @user.addresses.new(value: 'shipping')
    @user.addresses.new(value: 'billing')
  end
end
<%= semantic_form_for(@user) do |f| %>
  # ...
  # fields_for iterates through @user.addresses creating 
  # inputs for each
  <% f.semantic_fields_for :addresses do |a| %>
    <%= a.inputs :street %>
    <%= a.input :value,  as: :hidden %>
  <% end %>
<% end %>

哪个会给出以下参数哈希:

{
  user: {
    addresses_attributes: [
      {
        street: 'Wall Street',
        value: 'shipping'
      },
      {
        street: 'Broadway',
        value: 'billing'
      },
    ]
  }
}

请注意,正确的复数在这里非常重要! 然后,您可以将其传递给您的用户模型,accepts_nested_attributes将执行其余的工作。

class UsersController < ApplicationController
  # ...
  def create
    @user = User.new(user_params)
    if @user.save
      #...
    else
      # ...
    end
  end

  private
    def user_params
      params.require(:user)
            .permit(:email, :password, addresses_attributes: [:value, :street, :city]) # etc
    end
end