Kleber S.
Kleber S.

Reputation: 8240

Rails 3: Math between models

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

Answers (1)

mu is too short
mu is too short

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

Related Questions