Reputation: 8240
Suppose I have the following structure:
parts model:
- title
- weight
- part_type_id
part_type model:
- quotation
I want to set a "price" for each part. The models are using associations (parts:has_one) and (part_types:belongs_to). This is ok.
So, basically what I'm doing is creating an virtual attribute like this:
class Parts < ActiveRecords::Base
..
attr_accessor :price
def price
quotation = PartType.find(self.part_type_id).quotation
price = self.weight * quotation
end
end
And I can call it from the view like this:
<% @parts.each do |part| %>
<%= part.title %>
<%= part.price %>
<% end %>
Is this the "right" way for doing this or how should I do?
Upvotes: 1
Views: 354
Reputation: 434785
You might want to use attr_reader
to be paranoid:
attr_reader :price
Changing the price on its own doesn't make much sense so, since they really are out to get you, it is best to do away with a whole class of possible bugs with that small change. Then you'd want to alter your accessor to directly work with the instance variable that attr_reader
creates:
def price
return @price if(@price)
@price = PartType.find(self.part_type_id).quotation * self.weight
end
Presumably neither nil
nor false
are valid prices so you don't have to worry about computing the @price
over and over again if if(@price)
fails; the computation should only occur once as instance variables are automatically initialized to nil
on first access.
Looks sensible enough to me other than the minor nit mentioned above.
Upvotes: 1