Reputation: 25328
Here are my associations...
Account has_many :credits
Credit belongs_to :account
And I'm trying to run: account.credits.current
So, in that case, I've already got an Account
object, and then I want to access a current
method within the Credit
model.
Here is that method...
def self.current
# Find current credit line
current = self.where(:for_date => Time.now.strftime("%Y-%m-01")).first
# If we couldn't find a credit line for this month, create one
current = Credit.create(:account_id => self.account.id, :for_date => Time.now.strftime("%Y-%m-01")) if current.blank?
# Return the object
current
end
The problem is on that second line...the one that should create a new credit entry if it can't find one. Specifically, I can't set what account it should be associated with. I just get an undefined method 'account'
error.
Upvotes: 3
Views: 79
Reputation:
Create through association instead, and leave out the account_id
as it will be linked automatically:
current = self.create(:for_date => Time.now.strftime("%Y-%m-01")) if current.blank?
Note: self.create
instead of Credit.create
.
Upvotes: 1
Reputation: 43103
You're trying to access instance properties in a class method, that's not possible.
If you have this:
class Credit
def self.current
self.account
end
end
It's the same as: Credit.account
, which as I'm sure you understand, would not work.
Now, your method current
has to be a class method if you want it to load on the plural association: ie:
With def self.current
you can call account.credits.current
With def current
you can call account.credits[0].current
or account.credits.where(...).current
I hope this makes sense. Now, as for what to do about it...
My recommendation would be to make current
a scope, like so:
class Credit
scope :current, lambda { where(:for_date => Time.now.strftime("%Y-%m-01")).first }
...
end
Then you can use this scope anywhere and have an instance (or nil) at the end of it.
account.credits.create(...) unless accounts.credit.current
If you want to make a convenience method, I would then do:
class Credit def self.current_or_new self.current || self.create( :for_date => Time.now.strftime("%Y-%m-01") ) end end
This should work the way you are intending. If it's called through an association, ie:
account.credits.current_or_new
Then the account_id will be put in for you by rails through the association.
Upvotes: 0