嵌套属性用空父项预填充子数据
nested attributes prefilled child data with empty parent
我遇到了需要为 fields_for 提供空表格预填充数据的情况。让我举例说明
协会
class User < ApplicationRecord
has_one :account, foreign_key: :user_id
accepts_nested_attributes_for :account
end
Class Account
belongs_to :user
end
现在我在仪表板索引页上有一个表单。
<%= form_for @account, :url => account_path, html: { class: "abc" } do |f| %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= f.fields_for :user do |user| %>
<div class="medium-4 columns">
<label>First Name</label>
<%= user.text_field :first_name , class: 'xyz', data: {input: 'someinput'} %>
</div>
<div class="medium-4 columns">
<label><b>Last Name<span class="invalid_message"> This field is required</span></b></label>
<%= user.text_field :last_name, class: 'xyz', data: {input: 'someinput'} %>
</div>
<% end %>
<div class="medium-4 medium-offset-2 columns">
<label>Phone Number</label>
<%= f.text_field :phone_number, class: 'xyz', data: {input: 'someinput'} %>
</div>
<% end %>
控制器
class AccountsController < ApplicationController
def create
@account = Account.new(account_params)
if @account.save
render json: {status: 'successfull'}
else
render json: {error: "#{@account.errors.full_messages}"}, status: 400
end
end
private
def account_params
params.require(:account).permit(:phone_number, :user_id, user_attributes: [:first_name, :last_name])
end
end
class DashboardController < ApplicationController
def index
##I will always have current_user. For the account it will be blank for the first time
if current_user.account.blank?
@account = Account.new
else
@account = current_user.account
end
end
end
参数
{"utf8"=>"✓", "authenticity_token"=>"asdasdadadadadsadadadadadQpy0tA82asdaalAgJsUcNk1i/kGETfZqnuQA==", "account"=>{"user_id"=>"123", "user"=>{"first_name"=>"sd", "last_name"=>"ad"}, "phone_number"=>"1212"}}
有两个问题
1) 名字和姓氏没有被预填
2) 参数不正确。应该是account_attributes而不是参数中的account
注意:在我的例子中,@account 第一次是空白的,但用户对象(即当前用户)仍然有 first_name 和 last_name,我需要预先填写fields_for。另外,我需要一种更新名字和姓氏的方法
谁能告诉我哪里做错了
将 @account = Account.new
更改为 @account = current_user.build_account
。您应该会看到预填充的字段。
终于,我找到了解决办法。我做错了几件事
1) 在form_for中应该是@user而不是@account
2) 然后在控制器中,此表单将始终将其发送到更新操作而不是创建。原因是我将始终拥有 current_user,因此 rails 将自动检查对象 (current_user) 是否存在,而不是发送到创建,而是发送到更新操作
3) 最后,在使用一对一关联时,我们需要加载父对象并构建子对象。
<%= form_for @user, :url => user_path, html: { class: "abc" } do |f| %>
<div class="medium-4 columns">
<label>First Name</label>
<%= f.text_field :first_name , class: 'xyz', data: {input: 'someinput'} %>
</div>
<div class="medium-4 columns">
<label><b>Last Name<span class="invalid_message"> This field is required</span></b></label>
<%= f.text_field :last_name, class: 'xyz', data: {input: 'someinput'} %>
</div>
<%= f.fields_for :account do |account_info| %>
<div class="medium-4 medium-offset-2 columns">
<label>Phone Number</label>
<%= account_info.text_field :phone_number, class: 'xyz', data: {input: 'someinput'} %>
</div>
<% end %>
<% end %>
class UsersController < ApplicationController
def update
if current_user.update(account_params)
render json: {status: 'successfull'}
else
render json: {error: "#{@account.errors.full_messages}"}, status: 400
end
end
private
def account_params
params.require(:account).permit(:first_name, :last_name, account_attributes: [:phone_number])
end
end
class DashboardController < ApplicationController
def index
##I will always have current_user. For the account it will be blank for the first time
if current_user.account.blank?
@account = current_user
@account.build_account
end
end
end
我遇到了需要为 fields_for 提供空表格预填充数据的情况。让我举例说明
协会
class User < ApplicationRecord
has_one :account, foreign_key: :user_id
accepts_nested_attributes_for :account
end
Class Account
belongs_to :user
end
现在我在仪表板索引页上有一个表单。
<%= form_for @account, :url => account_path, html: { class: "abc" } do |f| %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= f.fields_for :user do |user| %>
<div class="medium-4 columns">
<label>First Name</label>
<%= user.text_field :first_name , class: 'xyz', data: {input: 'someinput'} %>
</div>
<div class="medium-4 columns">
<label><b>Last Name<span class="invalid_message"> This field is required</span></b></label>
<%= user.text_field :last_name, class: 'xyz', data: {input: 'someinput'} %>
</div>
<% end %>
<div class="medium-4 medium-offset-2 columns">
<label>Phone Number</label>
<%= f.text_field :phone_number, class: 'xyz', data: {input: 'someinput'} %>
</div>
<% end %>
控制器
class AccountsController < ApplicationController
def create
@account = Account.new(account_params)
if @account.save
render json: {status: 'successfull'}
else
render json: {error: "#{@account.errors.full_messages}"}, status: 400
end
end
private
def account_params
params.require(:account).permit(:phone_number, :user_id, user_attributes: [:first_name, :last_name])
end
end
class DashboardController < ApplicationController
def index
##I will always have current_user. For the account it will be blank for the first time
if current_user.account.blank?
@account = Account.new
else
@account = current_user.account
end
end
end
参数
{"utf8"=>"✓", "authenticity_token"=>"asdasdadadadadsadadadadadQpy0tA82asdaalAgJsUcNk1i/kGETfZqnuQA==", "account"=>{"user_id"=>"123", "user"=>{"first_name"=>"sd", "last_name"=>"ad"}, "phone_number"=>"1212"}}
有两个问题
1) 名字和姓氏没有被预填
2) 参数不正确。应该是account_attributes而不是参数中的account
注意:在我的例子中,@account 第一次是空白的,但用户对象(即当前用户)仍然有 first_name 和 last_name,我需要预先填写fields_for。另外,我需要一种更新名字和姓氏的方法
谁能告诉我哪里做错了
将 @account = Account.new
更改为 @account = current_user.build_account
。您应该会看到预填充的字段。
终于,我找到了解决办法。我做错了几件事
1) 在form_for中应该是@user而不是@account
2) 然后在控制器中,此表单将始终将其发送到更新操作而不是创建。原因是我将始终拥有 current_user,因此 rails 将自动检查对象 (current_user) 是否存在,而不是发送到创建,而是发送到更新操作
3) 最后,在使用一对一关联时,我们需要加载父对象并构建子对象。
<%= form_for @user, :url => user_path, html: { class: "abc" } do |f| %>
<div class="medium-4 columns">
<label>First Name</label>
<%= f.text_field :first_name , class: 'xyz', data: {input: 'someinput'} %>
</div>
<div class="medium-4 columns">
<label><b>Last Name<span class="invalid_message"> This field is required</span></b></label>
<%= f.text_field :last_name, class: 'xyz', data: {input: 'someinput'} %>
</div>
<%= f.fields_for :account do |account_info| %>
<div class="medium-4 medium-offset-2 columns">
<label>Phone Number</label>
<%= account_info.text_field :phone_number, class: 'xyz', data: {input: 'someinput'} %>
</div>
<% end %>
<% end %>
class UsersController < ApplicationController
def update
if current_user.update(account_params)
render json: {status: 'successfull'}
else
render json: {error: "#{@account.errors.full_messages}"}, status: 400
end
end
private
def account_params
params.require(:account).permit(:first_name, :last_name, account_attributes: [:phone_number])
end
end
class DashboardController < ApplicationController
def index
##I will always have current_user. For the account it will be blank for the first time
if current_user.account.blank?
@account = current_user
@account.build_account
end
end
end