I have two MySQL tables, Orders and Line_items. Orders has many
line_items. The line_item table has a quantity field and an item_price
field. In order.rb, I want to get the total price of the order. I try
def total_price
self.line_items.sum { |li| li.quantity * li.item_price}
end
and get "Wrong number of argument (1 for 2)
def total_price
self.line_items.each { |li| tpsum += (li.quantity * li.item_price)}
tpsum
end
"you have a nil item when you didn''t expect it. you might have
expected
an array..."
def total_price
self.line_items.each do |li|
tpsum = tpsum + (li.quantity * li.item_price)
end
tpsum
end
same error - nil when you didn''t expect it.
If I do
self.line_items.sum(:quantity)
I get an answer. That makes me think that I can treat line_items like
an array. How can I sum the product of two fields? Thanks.
--
Posted via http://www.ruby-forum.com/.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
You might prefer to use inject.
self.line_items.inject{|a, li| a += li.quantity * li.price}
On Feb 18, 2008, at 7:34 PM, Dick Kusleika wrote:
>
> I have two MySQL tables, Orders and Line_items. Orders has many
> line_items. The line_item table has a quantity field and an
> item_price
> field. In order.rb, I want to get the total price of the order. I
> try
>
> def total_price
> self.line_items.sum { |li| li.quantity * li.item_price}
> end
>
> and get "Wrong number of argument (1 for 2)
>
> def total_price
> self.line_items.each { |li| tpsum += (li.quantity * li.item_price)}
> tpsum
> end
>
> "you have a nil item when you didn''t expect it. you might
have
> expected
> an array..."
>
> def total_price
> self.line_items.each do |li|
> tpsum = tpsum + (li.quantity * li.item_price)
> end
> tpsum
> end
>
> same error - nil when you didn''t expect it.
>
> If I do
>
> self.line_items.sum(:quantity)
>
> I get an answer. That makes me think that I can treat line_items like
> an array. How can I sum the product of two fields? Thanks.
> --
> Posted via http://www.ruby-forum.com/.
>
> >
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
Hello,
have you tried it?
def total_price
@all_items = LineItems.find :all
@all_items.inject(0) { |sum, li| sum + (li.quantity *
li.item_price}
end
I not check my script above, i hope you can inform me if found any
error.
*~*~*~*~*~**~*~*~*~*~*
Reinhart Ariando
YM : Booking2Heaven
WEB : http://teapoci.blogspot.com
--
Posted via http://www.ruby-forum.com/.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
@Dick, In your first attempt I believe the problem is that you''re working against the association proxy. It looks a lot like an array, but it''s not. When you ask it to ''sum'', it''s actually trying to trigger a sum in the DB, rather than iterating through the line items. In the subsequent attempts, the problem is one of scope. tpsum is local to the block that you''re using. When you attempt to return it, however, you''re outside the block and in a context that knows nothing about tpsum. You could fix any of those solutions by simply initializing tpsum=0 before the block. s.ross, though, posts the more elegant solution. On Feb 18, 10:34 pm, Dick Kusleika <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> I have two MySQL tables, Orders and Line_items. Orders has many > line_items. The line_item table has a quantity field and an item_price > field. In order.rb, I want to get the total price of the order. I try > > def total_price > self.line_items.sum { |li| li.quantity * li.item_price} > end > > and get "Wrong number of argument (1 for 2) > > def total_price > self.line_items.each { |li| tpsum += (li.quantity * li.item_price)} > tpsum > end > > "you have a nil item when you didn''t expect it. you might have expected > an array..." > > def total_price > self.line_items.each do |li| > tpsum = tpsum + (li.quantity * li.item_price) > end > tpsum > end > > same error - nil when you didn''t expect it. > > If I do > > self.line_items.sum(:quantity) > > I get an answer. That makes me think that I can treat line_items like > an array. How can I sum the product of two fields? Thanks. > -- > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
def total_price
#self.line_items.inject{|a, li| a += li.quantity * li.item_price}
@all_items = self.line_items.find :all
@all_items.inject(0) { |sum, li| sum + (li.quantity *
li.item_price)}
end
@Steve - I get the following error when I use the one-liner that''s
commented out above.
undefined method `+'' for #<LineItem:0x4654ccc>
When I change it to
self.line_items.inject(0) {|a, li| a += (li.quantity * li.item_price)}
It works fine. I plan to do some reading on inject (first time I''ve
heard of it - kind of a noob), but if you''ve got any pointers
I''d love
the head start.
@Reinhart - works as implemented above, thanks.
@AndyV - thanks for the explanation. Local to the block, huh? I''m not
used to that. I better skip ahead to the "introduction to ruby"
section
of my book. Thanks again.
--
Posted via http://www.ruby-forum.com/.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
On Feb 19, 2008, at 6:22 PM, Dick Kusleika wrote:> > def total_price > #self.line_items.inject{|a, li| a += li.quantity * li.item_price} > @all_items = self.line_items.find :all > @all_items.inject(0) { |sum, li| sum + (li.quantity * > li.item_price)} > end > > @Steve - I get the following error when I use the one-liner that''s > commented out above. > > undefined method `+'' for #<LineItem:0x4654ccc> > > When I change it to > > self.line_items.inject(0) {|a, li| a += (li.quantity * li.item_price)} > > It works fine. I plan to do some reading on inject (first time I''ve > heard of it - kind of a noob), but if you''ve got any pointers I''d love > the head start. > > @Reinhart - works as implemented above, thanks. > > @AndyV - thanks for the explanation. Local to the block, huh? I''m > not > used to that. I better skip ahead to the "introduction to ruby" > section > of my book. Thanks again.I think you hit on it when you used 0 as the initializer for inject. By default, inject is supposed to used the first element of the enumerable as the starting value of the accumulator. That gives you a starting "a" of type LineItem, which is clearly not the intended type. By explicitly initializing it with a Fixnum, 0, you have created an accumulator (or memo) with a compliant type. So the corrected code: self.line_items.inject(0) {|a, li| a += li.quantity * li.item_price } should work without the parentheses around the product. The inject method is quite idiomatic and if you look at some of the inject/reject/select/map/zip methods, it will remind you of Python or perhaps of certain aspects of functional programming. If you''re not into that, inject is not a really obvious choice. --steve --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Technically, it''s local to the scope in which it was created, and the block has it''s own scope that''s ''nested'' within the scope of the total_price method. So... you could declare it in total_price and the block would see it, but not the other way around. On Feb 19, 9:22 pm, Dick Kusleika <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> def total_price > #self.line_items.inject{|a, li| a += li.quantity * li.item_price} > @all_items = self.line_items.find :all > @all_items.inject(0) { |sum, li| sum + (li.quantity * > li.item_price)} > end > > @Steve - I get the following error when I use the one-liner that''s > commented out above. > > undefined method `+'' for #<LineItem:0x4654ccc> > > When I change it to > > self.line_items.inject(0) {|a, li| a += (li.quantity * li.item_price)} > > It works fine. I plan to do some reading on inject (first time I''ve > heard of it - kind of a noob), but if you''ve got any pointers I''d love > the head start. > > @Reinhart - works as implemented above, thanks. > > @AndyV - thanks for the explanation. Local to the block, huh? I''m not > used to that. I better skip ahead to the "introduction to ruby" section > of my book. Thanks again. > -- > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
@Steve, @Andy - thanks for the help. You guys are great. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---