2

I have a form where a user types in a money value like 6.50

When the record is being saved, I want to save it in cents like 650.

How do I change the param

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

to

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

In the update method? I can't change it in the model—the int field will already chop off the .50

Mirror318
  • 11,875
  • 14
  • 64
  • 106
  • Provide the full controller code please. – Roman Kiselenko Sep 25 '17 at 05:26
  • This is bad practice adding workarounds like this. Things like this can lead you to different which will be rly hard to debug some time later. Why not just modify your column in db to store floats and run migration which will modify your integers to floats? – Avdept Sep 25 '17 at 11:29

2 Answers2

1

Yes, it is alright to do that in update method. Keep in mind, that since you are using strong-parameters you shouldn't change the params hash itself. Instead, change result parameters hash after it is whitelisted by 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

For better understanding of what I am talking about and possible problems see this (Modify ruby hash in place( rails strong params))

Another approach

You can convert value on the model level using virtual attribute. Whenever you set the virtual attribute (which is :value_in_dollars), it will convert and assign value attribute:

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

Using this approach you can pass your value as value_in_dollars from the form. The controller will look like this:

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
chumakoff
  • 6,807
  • 2
  • 23
  • 45
0

Try this:

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
cnnr
  • 1,267
  • 4
  • 18
  • 23