【问题标题】:form updating nested attributes when not required在不需要时更新嵌套属性
【发布时间】:2012-02-22 09:17:06
【问题描述】:

我有一个用户模型,它可以通过成员资格拥有许多组。如果用户是组的成员,并且您提交的表单没有更改,它将尝试更新成员表并将 group_id 设置为 0,如下所示。

我的用户模型 accept_nested_attributes_for Memberships

在我的用户控制器中...

    def edit
      @user = User.find(params[:id])
      @groups = Group.current
      @membership = @user.memberships.build
    end

    def update
      @user = User.find(params[:id])
      @groups = Group.current

      if params[:memberships][:group_id] != ""
        @membership = @user.memberships.build(:group_id => params[:memberships][:group_id])
      end

      respond_to do |format|
        if @user.update_attributes(params[:user])
          format.html { redirect_to admin_users_url, notice: 'User was successfully updated.' }
          format.json { head :no_content }
        else
          #if params[:memberships][:group_id] == ""
          #  @membership = @user.memberships.build
          #end
          format.html { render action: "edit" }
          format.json { render json: @user.errors, status: :unprocessable_entity }
        end
      end
    end

在我的用户表单中...

<%= form_for([:admin,@user]) do |f| %>
---
  <div class="field">
    <%= f.label :email %><br />
    <%= f.text_field :email %>
  </div>
  <div class="field">
    <%= f.label :password %><br />
    <%= f.password_field :password %>
  </div>
  <div class="field">
    <%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation %>
  </div>
    <%= f.fields_for :memberships do |builder| %>
  <div class="field">
    <% if builder.object.new_record? %>
        <%= builder.label :group_id %><br />
        <%= collection_select(:memberships, :group_id, @groups, 'id', 'name',    {:include_blank => true}) %>
    <% else %>
        <%= builder.label :group_id %><br />
        <%= builder.text_field :group_id, :value =>    Group.find(Membership.find(builder.object).group_id).name, :readonly => true %> <%= link_to 'Remove', [:admin,@user,Membership.find(builder.object)], :confirm => 'Are you sure?', :method => :delete %>
    <% end %>
  </div>
    <% end %>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

表单正在提交数据

Parameters: {"utf8"=>"✓", 
"authenticity_token"=>"6Vp9sgMySzRm2CU9Dko+Jpf6yaBkXjKkt10UDbb8dcw=", 
"user"=>{"email"=>"asdfasdf@asdf.com", 
"password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", 
"memberships_attributes"=>{"0"=>{"group_id"=>"Cricket Maidstone June 2012",
"id"=>"18"}}}, 
"memberships"=>{"group_id"=>""}, 
"commit"=>"Update User", "id"=>"25"}

我要做的就是检查表单,如果 collection_select 字段中没有任何内容,则不更新成员资格表,但仍会更新对电子邮件/密码的任何更改。任何人都可以看到这样做的方法吗?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3


    【解决方案1】:

    在您的模型中,使用 attr_accessor 声明一个并行字段:

    attr_accessor :memberships_attributes_input
    
    def memberships_attributes_input
        memberships
    end
    
    def memberships_attributes_input=value
        # Update memeberships if required evaluating 'value'.
    end
    

    在您的表单中使用这个新字段而不是“会员资格”。

    【讨论】:

    • 我会投票赞成,因为在调查它时,这似乎可行,但我做错的是在表格中包含每个现有的成员资格,因此将选择框留空会尝试设置表单中的所有字段。我不应该包含