嵌套属性不会更新rails

时间:2014-08-21 20:26:59

标签: ruby-on-rails simple-form nested-attributes

这一天大部分时间都让我难过。我正在尝试为连接表创建嵌套表单。

  • 一份工作有很多工作地点
  • 通过工作地点找到工作地点
  • 工作地点属于工作和地点
  • 工作地点有很多
  • 一个地点有很多工作地点
  • 一个地点通过地点有很多工作

我希望用户从可能的5个位置中进行选择,这些位置在数组中具有各自的ID。用户从作业页面的编辑操作中选择这些位置,因此我通过执行以下操作来获取作业ID:

@job.job_locations.build

这是我被困的地方。

我已添加到我的工作模式accepts_nested_attributes_for :job_locations,按照协会的顺序排在下面。

然后我的表格

     =simple_form_for edit_admin_job_path(@job) do |f|
      =f.simple_fields_for :job_locations do |p|
        =p.input :location_id, collection: @common_locations_array
        =f.submit

我错过了什么?

我使用的是Rails 4,haml和简单的表单。

更新

它可以是嵌套表单中的我的集合吗?该集合包含该位置的所有信息,而不仅仅是id。我不能设置输入值吗?我该怎么做?

添加了控制器操作

def edit
    unless @job = Job.find_by(id: params[:id])
      flash[:error] = "Job could not be found"

      if @job_subject
        redirect_to(admin_polymorphic_jobs_path(@job_subject))
      else
        redirect_to root_path # points to /admin/searches/new
      end
    end
    @job.job_locations.build
    @location = Location.new
    @client = @job.client 
    @locations_grouped_hash = JobLocation.group(:location_id).distinct.count(:id)
    @common_locations_hash = @locations_grouped_hash.sort_by { |k, v| v }.reverse.first(5).to_h
    @common_locations_array = []
    @common_locations_hash.each do |k, v| 
      @common_locations_array << Location.find(k)
    end


    @job_types = JobType.get_all_job_types
  end



  # PUT-PATCH /admin/jobs/:id                        admin_job_path
  # PUT-PATCH /admin/clients/:client_id/jobs/:id     admin_client_job_path
  # PUT-PATCH /admin/contacts/:contact_id/jobs/:id   admin_contact_job_path
  def update
    @job = Job.find_by(id: params[:id])
      was_frozen = @job.workflow_frozen?

      @job.assign_attributes(job_params)
      job_changes = @job.changes
      will_be_frozen = @job.workflow_frozen?  
      # this MUST be atomic!
      ActiveRecord::Base.transaction do
        @job.freeze_stock! if (will_be_frozen && !was_frozen)
        if @job.save
          flash[:success] = "attributes updated"
        else
          flash[:error] = "Couldn't update the job. Please check for errors."
          @job_types = JobType.get_all_job_types
          render('admin/jobs/edit') and return
        end
        @job.unfreeze_stock! if (!will_be_frozen && was_frozen)
      end


      # We clear the associations before proceeding, because even
      # if params[:locations] is missing, it just means that the
      # user has deselected all of them before submitting
      @job.locations.clear

      # ...and here we re-add only the selecred ones
      if params[:locations]
        params[:locations].each do |loc_id|
          this_location = Location.find_by(id: loc_id)
          @job.locations << this_location if this_location
          # we can safely assume that all of these locations already belong to the client
        end
      end

      # OLD - replaced by NEW, below:
      #    We clear the associations before proceeding, because even
      #    if params[:contacts] is missing, it just means that the
      #    user has deselected all of them before submitting
      # @job.contacts.clear
      if params[:contacts]
        # NEW
        # first we need to remove the "not selected" contacts
        new_contact_ids = params[:contacts].map { |item| item.to_i }
        @job.contacts.each do |associated_contact|
          unless new_contact_ids.include?(associated_contact.id)
            @job.contacts.delete(associated_contact)
          end
        end

        # and now we add the selected ones
        # (we assume that all of these contacts already belong to the client)
        new_contact_ids.each do |new_contact_id|
          this_contact = Contact.find_by(id: new_contact_id)
          begin
            @job.contacts << this_contact if this_contact
          rescue ActiveRecord::RecordInvalid
            # the contact was already assigned
          end
        end
      else
        # all unchecked, let's remove them all
        @job.contacts.clear
      end
      AdminActivity.job_details_updated!(current_admin, @job, job_changes)
      redirect_to edit_admin_job_path(@job)


  end

由于

1 个答案:

答案 0 :(得分:1)

我相信您需要= p.input :location_id, collection: @common_locations_array而不是=f.input,因为您正在为location_id更新job_location

<强>更新

与@ user3868832聊天后,他不得不更新:

=simple_form_for edit_admin_job_path(@job) do |f|

=simple_form_for :job do |f|

允许他的表单实际点击update操作。