I am maintaining an application that has an account model which has many
payments. So the account model has a has_many relationship as shown
below:
class Account < ActiveRecord::Base
…
has_many :payments, :order => “created_at ASC” do
def charge(amount, paying_for)
Payment.charge(proxy_owner, amount, paying_for)
end
def commit(action, amount, paying_for)
Payment.commit(proxy_owner, action, amount, paying_for)
end
def gift(days = nil)
Payment.gift(proxy_owner, days)
end
end
…
end
This may be an RoR 101 question, but why would someone define methods in
a has_many block? Can’t this be simply called as:
account_inst.payments.charge(amount, paying_for) for example?
I do not understand what is the benefit of defining (or proxying ) class
methods belonging to the many side of this relationship in this manner?
Thanks for your time.
Bharat
On Jul 19, 10:14 pm, Bharat R. [email protected]
wrote:
This may be an RoR 101 question, but why would someone define methods in
a has_many block? Can’t this be simply called as:
It’s nicer to write some_account.payments.gift than it is to write
Payment.gift(some_account). You get the association scoping for free
which can help you avoid mistakes and make things more readable.
account_inst.payments.charge(amount, paying_for) for example?
That is precisely what the association extension methods that have
been defined allow you to do.
One trick that is not well known enough is that if foo is a class
method on payments then you can call
account_inst.payments.foo() and it will call the class method foo
except that everything will be scoped to only act on those payments
belong to foo. This won’t work with the existing charge method since
it requires an account as its first parameter.
Fred
I do not understand what is the benefit of defining (or proxying ) class
methods belonging to the many side of this relationship in this manner?
Thanks Fred. You wrote:
“This won’t work with the existing charge method since
it requires an account as its first parameter.”
Was this an oversight since the first parameter of the existing charge
method is amount as shown below?
def charge(amount, paying_for)
Payment.charge(proxy_owner, amount, paying_for)
end
Nice explanation.
Regards,
Bharat
On 20 Jul 2008, at 17:35, Bharat wrote:
Thanks Fred. You wrote:
“This won’t work with the existing charge method since
it requires an account as its first parameter.”
Was this an oversight since the first parameter of the existing charge
method is amount as shown below?
No - what i meant that the charge method you would get for free on the
payments association (because of the existence of Payment.charge)
wouldn’t do the write thing.
Fred