Rake task to fetch current price and update object attribute

518 views Asked by At

I have a Portfolio model and am currently running rake tasks to fetch updated price data from Yahoo Finance API, updating the amounts for the Portfolios and create a new Valuation object that takes a snapshot of each portfolio and their values.

A Portfolio has_many Positions that store tickers and their prices. Positions has a has_many association to Movements that act as buy/sell actions and add/subtract from a Portfolio's amount.

The Portfolio methods I'm using to fetch updated price data and update my portfolio amount are:

def new_price_data
  price_array = []
  if !positions.empty?
    positions.each do |pos|
      price = YAHOO_CLIENT.quotes([pos.ticker], [:last_trade_price]).first
      price = price['last_trade_price'].to_f
      price = price * pos.quantity
      price_array << price
    end
  else
    price_array << 0
  end
  price_array
end

def calculate_amount
  price = self.new_price_data.inject(&:+)
  price
end

def update_portfolio_amount
  update_attribute(:amount, self.calculate_amount.round(2))
end

In my rake file I have an update_price task in the valuation namespace:

desc "Retrieve real-time price data" 
task update_price: :environment do
  Portfolio.all.each do |portfolio|
    portfolio.update_portfolio_amount
  end
end

When I run the body of the task (Portfolio.all.each...) it runs on all my Portfolio objects. For some reason it doesn't run when I schedule it in my cron tab with whenever.

every 1.day, :at => '1:55 am' do
  rake "valuation:update_price", :environment => 'development'
end

My other rake task that is simply creating a new Valuation object on all Portfolios and taking a snapshot of their values for a given day works fine.

I've tested this using rake valuation:update_price. There is a message saying

Running via Spring preloader in process 23522

but when I check my Portfolios my rails console, they haven't updated. I'm not sure where my error is?

I've done some more digging and when the Portfolio object makes changes to its positions (creating new ones, buying or selling shares) the #update_portfolio_amount is run. If I run it again, the method returns nil. Since the body of the method is running #update_attribute, I've been trying to figure out what would cause it to return nil. I've only found sources for the #update_attributes returning nil but not the singular one.

What could cause the nil return value in #update_attribute?

0

There are 0 answers