KevL
KevL

Reputation: 403

How to populate rails table with data from other tables?

I'm a bit of a noob programmer so apologies if the question isn't clear enough.

I'm trying to create a basic rails app where I have 3 different tables: usages(month, usage), prices(month, price) and spends(month, spend). I'm trying to get it so that spend = usages.usage * prices.price. I've put the following code into my Spend model:

class Spend < ActiveRecord::Base
  c = Usage.all.count
      i = 1
      while i <= c
          u = Usage.find(i)
          p = Price.find(i)
          Spend.create(month:u.month, spend:u.usage*p.price)
          i += 1
      end
end

This works great initially, but as soon as I start adding and removing usages and prices, their id's change so it isn't as clear cut. How can I do this in a much better way?

Thanks,

Kev

Upvotes: 1

Views: 1454

Answers (2)

PinnyM
PinnyM

Reputation: 35533

In this case, I would lean against making a separate Spend model, since all it does is calculate data that is already present in the database. Unless you have severe caching requirements (and I doubt it in your case), you can use simple instance methods to retrieve the data you want.

First figure out how your Usage and Price models are related. Since you seem to be associating them by id, it appears to be a one-to-one relationship (correct me if I'm wrong on this). However, associating by assuming they have the same primary key is a dangerous approach - rather have one model point to the other using a foreign key. We'll pick the Price model to hold a primary key for Usage, but the reverse can also work. You'll need to add a column using a migration like this:

def change
  add_column :prices, :usage_id, :integer
end

Your models should then look like this:

class Usage < ActiveRecord::Base
  has_one :price

  def spend
    usage * price.price
  end
end

class Price < ActiveRecord::Base
  belongs_to :usage
end

And you can find your spend value for an individual usage item like this:

usage = Usage.find(some_id)
puts usage.spend

Or you can get multiple 'spends' like this:

Usage.include(:price).each do |usage|
  puts usage.spend
end

I've left out any reference to month, as I'm not sure how you are using it or if it's needed at all for calculating spend.

Upvotes: 2

user934801
user934801

Reputation: 1139

Have a look at the Active Record association guide: http://guides.rubyonrails.org/association_basics.html

Upvotes: 0

Related Questions