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?