更新操作rails中缺少参数

时间:2014-07-23 16:22:42

标签: ruby-on-rails ruby

导致此更新操作无效的原因是什么?当我调试控制器时,所有实例变量似乎都包含正确的数据,但我留下了错误param is missing or the value is empty

这是简略表格

 = simple_form_for [:admin, @job, @new_delivery] do |f|
    - if jdc.new_record?
      %tr
        %td
         .......
          = f.input :quantity, label: false
       ......
          = f.submit "Add", class: "btn btn-s btn-default"
    - else
      %tr
        %td
          .......
          = jdc.delivery_cost.unit
        %td
       .........
        %td
          = link_to 'Delete', admin_job_job_delivery_cost_path(@job, jdc), method: :delete, class: "btn btn-xs btn-danger"
        %td
          = link_to 'Update', admin_job_job_delivery_cost_path(@job, jdc), method: :patch, class: "btn btn-xs btn-info"

我将在下面添加相关的控制器操作:

  def update
    set_job_delivery_cost 
    if @job.present? && @job_delivery_cost.present?
          @job_delivery_cost.update_attributes(job_delivery_cost_params)
      raise @job.inspect
      if @job_delivery_cost.save
        flash[:success]="Changes Saved"
      else
        flash.now[:error]="Check for Errors"
        return render('admin/client_types/edit')
      end
    end
    redirect_to admin_job_job_delivery_costs_path(@job)
  end

  def set_job_delivery_cost
    @job_delivery_cost ||= JobDeliveryCost.find_by(id: params[:id])
  end

  def job_delivery_cost_params
    params.require(:job_delivery_cost).permit!
  end

这些是请求参数:

{"_method"=>"patch", "authenticity_token"=>"66fRYMn6/2ges7JU75d5sWUausx8GJvM5dsNpbRxlYQ=", "action"=>"update", "controller"=>"admin/job_delivery_costs", "job_id"=>"53", "id"=>"17"}

服务器日志......

Started PATCH "/admin/jobs/53/job_delivery_costs/17" for 127.0.0.1 at 2014-07-23 18:36:27 +0100
Processing by Admin::JobDeliveryCostsController#update as HTML
  Parameters: {"authenticity_token"=>"66fRYMn6/2ges7JU75d5sWUausx8GJvM5dsNpbRxlYQ=", "job_id"=>"53", "id"=>"17"}
  Job Load (0.4ms)  SELECT `jobs`.* FROM `jobs` WHERE `jobs`.`id` = 53 LIMIT 1
  JobDeliveryCost Load (0.4ms)  SELECT `job_delivery_costs`.* FROM `job_delivery_costs` WHERE `job_delivery_costs`.`id` = 17 LIMIT 1
Completed 500  in 6ms

ActionController::ParameterMissing - param is missing or the value is empty: job_delivery_cost:

送货费用.rb

# == Schema Information
#

# Table name: delivery_costs
#
#  id            :integer          not null, primary key
#  title         :string(255)
#  unit          :string(255)
#  cost_per_unit :float
#  created_at    :datetime
#  updated_at    :datetime
#

class DeliveryCost < ActiveRecord::Base

  UNIT_DAY='day'
  UNIT_HOUR='hour'
  UNIT_MILE='mile'
  UNITS=[UNIT_DAY,UNIT_HOUR,UNIT_MILE]

  has_many :job_delivery_costs
  has_many :jobs, through: :job_delivery_costs

  validates :cost_per_unit, presence: true
  validates :unit, inclusion: UNITS
  validates :title, presence: true
  before_destroy :survive_if_jobs

  private

  def survive_if_jobs
    jobs.empty?
  end
end

job_delivery_cost.rb

# == Schema Information
#
# Table name: job_delivery_costs
#
#  id               :integer          not null, primary key
#  job_id           :integer
#  delivery_cost_id :integer
#  cost_per_unit    :float
#  quantity         :integer
#  timing           :string(255)
#  created_at       :datetime
#  updated_at       :datetime
#

class JobDeliveryCost < ActiveRecord::Base
  TIMING_INSTALL='install'
  TIMING_BREAKDOWN='breakdown'

  TIMINGS=[TIMING_INSTALL,TIMING_BREAKDOWN]

  belongs_to :delivery_cost
  belongs_to :job
  validates :quantity, presence: true, numericality: {greater_than_or_equal_to:1}
  validates :timing, inclusion: TIMINGS
  #validates :cost_per_unit, presence: true

validate :validate_cost_per_unit
  validate :check_associates
  # validate :quantity_default
  before_save :init


  private

  def check_associates
    associated_object_exists DeliveryCost, :delivery_cost_id
    associated_object_exists Job, :job_id
  end

  def validate_cost_per_unit
    if delivery_cost and cost_per_unit.blank?
      self.cost_per_unit=delivery_cost.cost_per_unit
    end
    return false if cost_per_unit.blank?
  end

    def init
      if self.quantity.nil?
        self.quantity = 1
      end
    end

end

2 个答案:

答案 0 :(得分:0)

错误应在您的行params.require(:job_delivery_cost).permit!中。这是因为您实际上并未将表单发送到更新操作。

您应该更改以下行:

link_to 'Update', admin_job_job_delivery_cost_path(@job, jdc), method: :patch, class: "btn btn-xs btn-info"

使用实际的提交按钮,如下所示:

f.submit 'Update', class: "btn btn-xs btn-info"

然而,要使其正常工作,您需要将表单操作和方法更改为更新操作。

答案 1 :(得分:0)

问题在于job_delivery_cost字段未通过params传递。所以我看到处理变量的三个变体:

  1. belongs_to :job_delivery_cost添加到DeliveryCost,然后您必须将job_delivery_cost分配给可见输入或隐藏的输入:

    1. 可见实际输入:

      = f.input :job_delivery_cost
      
    2. 隐藏输入,因此您无法明确更改:

      = f.input :job_delivery_cost, as: hidden, label: false
      
  2. 尝试读取DeliveryCost模型实例的值:

    = f.input :job_delivery_cost, as: hidden, label: false, value_method: :job_delivery_cost
    

    和型号:

    class DeliveryCost
    # ...
      def job_delivery_cost
        # ... some code to return job_delivery_cost
      end
    end
    
  3. 只需删除params job_delivery_cost字段的要求,然后根据ID计算。