I am trying to build an app in the "rails way", so this time instead of retrospectively processing records in the database, I am trying to do them using a before_save method, namely this one:
def make_percentage_from(score)
percent = (score.fdiv(20) * 100)
return percent
end
Every item that comes into the database has a score out of 20, before it gets saved to the database I would like to store this as a percentage, however the issue I am having is that I am unable to send any attribute data via a before_save.
Ideally I'd have
before_save :make_percentage_from(score-to-be-calculated)
How can I do this? Google isn't turning up so much for me and I'm determined not to have to process this data once its stored (providing of course there is another way!)
Thanks and regards
Geoff
The short answer: callbacks never have parameters. It is assumed that callbacks take action on the object or record itself. So anything that you would need as a parameter you would need to store either as an attribute (which is saved to the database) or as an instance variable.
If score
and percentage
are attributes of Widget
:
class Widget < ActiveRecord::Base
before_validates :calculate_score_percentage
validates :percentage, :presence => true
private
def calculate_score_percentage
self.percentage = score.fdiv(20) * 100
end
end
This works because all of your attributes/columns have getter and setter methods automatically defined by ActiveRecord. The reference to score
in the calculate_score_percentage
method is actually calling the self.score
method, which will return the score
object/value. We have to use self.percentage
explicitly because it would be ambiguous to use percent
alone — it could be either defining a local percentage
variable, or calling self.percentage=
. The default would be the former, which is not what we want in this case.
I'm using before_validates
to show that you can use validation still here, which is good for some sanity checking. If you didn't want to do any validation, you could swap it out for before_save
without any code changes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With