使用 Formtastic 为一个用户创建多个地址
Create multiple Addresses for one User with 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 制作)看起来像这样(outtake):
= 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' }
问题是站点参数中只存在后一个地址,因此只会创建一个。
如何为同一用户创建多个地址?
要创建嵌套记录,您应该为记录播种并将关联传递给 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
我目前在我的 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 制作)看起来像这样(outtake):
= 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' }
问题是站点参数中只存在后一个地址,因此只会创建一个。
如何为同一用户创建多个地址?
要创建嵌套记录,您应该为记录播种并将关联传递给 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