Reputation: 41
First of all sorry for this simple question, after spending a lot of time I have given up finding it without any help :(.
Simplified I have the following situation: one table rates
with columns rate
and converted
generated with the scaffold statement within ruby. The column rate
will be shown in the view, but the converted
column not which will only be used in the background of the application.
Now it's my goal to ask the user for a rate given in the field rate
so the application can calculate the converted
and store this value in the database. It's a simple calculation: converted
= 1 / rate.
Please advice :).
Upvotes: 2
Views: 959
Reputation: 34176
Well there are a ton of ways to do that, including but not limited to putting the logic in the model (probably cleanest), in the controller and in the view itself with a hidden field and javascript.
I would do it at the model level with a callback. For example, add this to your rates.rb model:
before_save :calculate_converted_rate
private
def calculate_converted_rate
self.converted = 1.0 / self.rate
end
Which as the code might suggest sets the converted field to the inverse of the rate field each time before a Rates instance is saved.
More information on ActiveRecord callbacks: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
Upvotes: 3
Reputation: 2923
Define your own mutator method in your model. This will allow you to take the input from your user, do what you want with it, then store it in the database. To illustrate:
class Rate < ActiveRecord::Base
def rate=(value)
write_attribute :rate, value
write_attribute :converted, 1.0 / value
end
end
This will override Rails' default rate=
method, which is what gets called when your model is passed your rate
data from (assumedly) your form. Construct your model's form normally, with a <%= f.text_field :rate %>
or whatever you need to do.
Note the 1.0 / value
, not 1 / value
- this will ensure the result of that expression is a float, and that you won't lose any precision. If you divide an integer by an integer in Ruby, you'll always get an integer.
Upvotes: 2