我有一个用户has_one配置文件,但不是所有用户都需要配置文件。我正在寻找一种方法来创建配置文件,只有当一个复选框被选中的用户表单(无论是通过更新或创建)。
我的模特是这样的-
class User < ActiveRecord::Base
has_one :profile
accepts_nested_attributes_for :profile
class Profile < ActiveRecord::Base
belongs_to :user
理想情况下,在我的用户表单中,我想包括一个复选框,当选中这将创建配置文件并将配置文件中的user_id设置为相应的用户ID。
我知道在我的用户控制器中,执行
@user.build_profile
将在更新时创建配置文件,但不是所有用户都需要创建配置文件。
在表单中创建一个复选框,但不使用form_for符号'f'。而是使用check_box_tag
check_box_tag :create_profile
现在在您的创建/更新函数中创建配置文件,如果选中此框
@user.build_profile if params[:create_profile]
我正在尝试类似的东西(使用Rails 4.2.4),并得出了这个解决方案。
应用程序/模型/user.rb
allow_destroy: true
将允许您通过用户表单销毁配置文件关联(在这里更多)。
class User < ActiveRecord::Base
has_one :profile
accepts_nested_attributes_for :profile, allow_destroy: true
app/controllers/users_controller.rb
您需要构建用户关联的配置文件实例(在new
和edit
方法中),以便在各自的形式中正确工作。
在编辑用户时,可能已经存在配置文件关联。如果关联的配置文件存在,edit
方法将使用它(用它的值设置表单),如果不存在,则创建一个新的配置文件实例。
还请注意,user_params
包括profile_attributes: [:_destroy, :id]
,这将是复选框发送的值。
def new
@user = User.new
@user.build_profile
end
def create
@user = User.new(user_params)
if @user.save
redirect_to root_path
else
render :new
end
end
def edit
@user.profile || @user.build_profile
end
def update
if @user.update(user_params)
redirect_to @user
else
render :edit
end
end
private
def user_params
params.require(:user).permit(:name, profile_attributes: [:_destroy, :id])
end
app/views/用户/new.html。rb 和 app/views/用户/edit.html.rb
在表单中使用fields_for
方法提交关联的数据(更多关于嵌套属性的信息,特别是一对一关系,在这里)。
使用复选框destroy
属性来创建/销毁关联的配置文件。花括号内的checked
属性的值根据关联是否存在设置复选框的默认状态(更多内容在这里的"更复杂的关系"标题下)。接下来的'0'
和'1'
与destroy
方法相反(即,如果复选框被选中,则创建关联,如果未选中则删除关联)。
<%= form_for @user do |user| %>
<%= user.fields_for :profile do |profile| %>
<div class='form-item'>
<%= profile.check_box :_destroy, { checked: profile.object.persisted? }, '0', '1' %>
<%= profile.label :_destroy, 'Profile', class: 'checkbox' %>
</div>
<% end %>
<%= user.submit 'Submit', class: 'button' %>
<% end %>
您可能还可以从配置文件模型中删除主键id
,因为在这种情况下它是不必要的,并且这个链接在这方面非常有用。