Rails-修改控制器中的嵌套参数

时间:2017-09-25 05:13:29

标签: ruby-on-rails ruby-on-rails-5 strong-parameters

我有一个表单,用户可以在其中输入货币值6.50

保存记录时,我希望将其保存为美分650

如何更改参数

center: { ticket_attributes: { value: '6.50' } }

center: { ticket_attributes: { value: '650' } }

update方法中?我无法在模型中更改它 - int字段已经切断了.50

2 个答案:

答案 0 :(得分:0)

试试这个:

def method_where_you_want_to_change_params
  if resource_params[:resource_name].present?
    new_ticket_attributes = resource_params[:ticket_attributes]
    param_to_change = new_ticket_attributes[:value]
    param_to_change = params_to_change * 100
    new_ticket_attributes[:value] = param_to_change
  end

  modified_params = resource_params
                    .except(:ticket_attributes)
                    .merge(:new_ticket_attributes)

  # work with your resource as you need, create or modify
  # for example
  @resource = resource_class.new modified_params
end

protected

def resource_params
  params.permit(... list of your params, as usual...)
end

答案 1 :(得分:0)

是的,可以在update方法中执行此操作。请注意,由于您使用的是strong-parameters,因此您不应更改params哈希本身。相反,在strong-parameters列入白名单后更改结果参数哈希:

class TicketsController < ApplicationController

  def update
    # first, get whitelisted params
    update_params = update_ticket_params
    # then perform convertion
    update_params[:value] = value_in_cents(update_params[:value])

    @ticket.update(update_params)
    # ...
  end

  private

  def update_ticket_params
    params.require(:ticket).permit(:value, ...)
  end

  def value_in_cents(value_in_dollars)
    # TODO: convert dollars to cents
  end
end

为了更好地理解我所谈论的内容和可能存在的问题,请参阅此内容(Modify ruby hash in place( rails strong params)

另一种方法

您可以使用虚拟属性在模型级别转换值。每当您设置虚拟属性(:value_in_dollars)时,它都会转换并分配value属性:

class Ticket < ApplicationRecord
  attr_accessor :value_in_dollars

  # whenever you set :value_in_dollars, it converts and assigns :value
  def value_in_dollars=(value)
    self.value = value_in_cents(value)
  end

  private

  def value_in_cents(value_in_dollars)
    # TODO: convert dollars to cents
  end
end

使用此方法,您可以将值从表单传递为value_in_dollars。控制器将如下所示:

class TicketsController < ApplicationController

  def update
    @ticket.update(update_ticket_params)
    # ...
  end

  private

  def update_ticket_params
    # expect 'value_in_dollars' value from the form, not 'value'
    params.require(:ticket).permit(:value_in_dollars, ...)
  end
end