Undefined Method error when creating method for collection of objects


#1

Hi I am learning rails and have hit a bit of a wall.

I have created methods previousley that work fine on a single object.
However in my latest project I am trying to calculate the total cost
of a group of phonecalls and I am having difficulty creating a method
to calculate this. I have a phonecall model and phonecall has a cost
attribute.

In my controller I am finding the @phonecalls
And in my view I want to say @phoncalls.total_cost

However I keep getting an undefined method error.

In my phonecall model i am trying to iterate through a block.

def total_cost

totalcost=0

each do |phonecall|
totalcost += phonecall.cost
end

totalcost
end

I have tried varios types of blocks, various connertaions of this
method and self.each… but I dont seem to be getting anywhere.

I am not sure if this is because of the fact that my syntax is wrong
when dealing with a collection of objects as I am in this case.

I can iterate through those objects in the view ie for each phonecall
in @phonecalls etc and I am getting the correct output o I am happy
that the controller code is working fine.

Any help would be muchly appreciated as I am struggling to find help
in my books and online.

Thank you


#2

On 2 Apr 2009, at 11:35, Rick wrote:

And in my view I want to say @phoncalls.total_cost

end

You’ve defined a total_cost method on the PhoneCall class, but you’re
trying to call it on an instance of Array (that just happens to
contain phone calls)
The easiest way is probably to create a class method that takes as an
argument the array and returns the total cost.

Fred


#3

On 2 Apr 2009, at 11:59, Frederick C. wrote:

In my controller I am finding the @phonecalls
And in my view I want to say @phoncalls.total_cost

The easiest way is probably to create a class method that takes as an
argument the array and returns the total cost.

You could also run in your view e.g. @phonecalls.sum { |p| p.cost }

-Matt


#4

Hi Matt, Thanks for your time.

I thought that by putting my total_cost method in the phonecall model
that I was doing exactly that.

I appreciate that I can use the view shortcut so thanks for that tip.
I do need to understand how to create methods that act upon an array
of objects both in this instance and obviousley for my future
understanding of this subject.


#5

On Apr 2, 11:59 am, Frederick C. removed_email_address@domain.invalid
wrote:

attribute.
argument the array and returns the total cost.

Fred

Hi Fred thnaks for your time.

I thought that I had created a class method in the (phonecall class) .
Do you mean in the array class? And how do I do that. Is it not
possibl;e to create methods in the phonecall model file that act upon
a collection(array) of that object or do they have to be acting only
on a single instance of that object.

Once again thanks for your time.


#6

Hi Frederick,

Once again thankyou for taking the time to respond.

I am a little confused by your response.

Your method seems to suggest that I pass an argument/array into the
method.

@phonecalls should already contain all of the array data, no? Why do I
need to pass this in. Cant I just create a method that acts upon the
multiple objects of @phonecalls ?

Thanks

Richard

On Apr 2, 4:14 pm, Frederick C. removed_email_address@domain.invalid


#7

On Apr 2, 2:00 pm, Rick removed_email_address@domain.invalid wrote:

On Apr 2, 11:59 am, Frederick C. removed_email_address@domain.invalid
wrote:

Hi Fred thnaks for your time.

I thought that I had created a class method in the (phonecall class) .
Do you mean in the array class? And how do I do that. Is it not
No. (well technically you could create methods on the Array class but
that would be messy).

you’d want something like

def self.total_cost(array_of_phone_calls)

end

and then PhoneCall.total_cost(some_array)

Fred


#8

On Apr 3, 12:37 am, Rick removed_email_address@domain.invalid wrote:

need to pass this in. Cant I just create a method that acts upon the
multiple objects of @phonecalls ?

@phonecalls is an Array, so to be able to do @phonecalls.total_cost
you would have to add a total_cost method to Array. If you start doing
this willy nilly, Array will very quickly have dozens of methods that
only apply if the array contains elements of some particular class
that sounds really horrible. (the are alternatives, like extending AR
to return a result set proxy instead of an array etc. but that’s
rather out of scope)

Fred