Rails使用build with复选框与has_one关联



我有一个用户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

您需要构建用户关联的配置文件实例(在newedit方法中),以便在各自的形式中正确工作。

在编辑用户时,可能已经存在配置文件关联。如果关联的配置文件存在,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,因为在这种情况下它是不必要的,并且这个链接在这方面非常有用。

相关内容

  • 没有找到相关文章

最新更新