Forum: Ruby on Rails Examples for Money library ?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Ff82af3238a57fbd1212832ec1a19f28?d=identicon&s=25 Dylan Stamat (Guest)
on 2006-02-28 02:08
(Received via mailing list)
Can anybody share some examples of their Money implementation ?

I'm trying to setup a Model to use this library, but can't seem to wrap
my
head around how it is exactly supposed to work.
My Model (Foo) looks like:
===============
composed_of :commission, :class_name => "Money", :mapping => [
%w(commission_cents cents), %w(commission_currency currency) ]

Yet, in script/console, I'm unable to get the correct behaviour (at
least I
think), from the library.
===============
>> t = Foo.new(:commission => 34)
NoMethodError: undefined method `cents' for 34:Fixnum
        from (eval):3:in `commission='


I've tried just playing with the Money object as well, but regardless of
what number I pass into the Money constructor, it always provides me
with
the exact number I specify as the "cents" value.  So, If I do:
Money.new(
34.43)... it tells me that the instance has 34 cents.

I must be overlooking something.  Any insight would be greatly
appreciated !
59de94a56fd2c198f33d9515d1c05961?d=identicon&s=25 Tom Mornini (Guest)
on 2006-02-28 04:23
(Received via mailing list)
On Feb 27, 2006, at 5:06 PM, Dylan Stamat wrote:

> least I think), from the library.
> ===============
> >> t = Foo.new(:commission => 34)
> NoMethodError: undefined method `cents' for 34:Fixnum
>         from (eval):3:in `commission='

Try:
   t = Foo.new(:commission => Money.new(34))

or

   t=Foo.new
   t.commission = Money.new(34)

--
-- Tom Mornini
Ff82af3238a57fbd1212832ec1a19f28?d=identicon&s=25 Dylan Stamat (Guest)
on 2006-02-28 05:37
(Received via mailing list)
Hey Tom !  That does work... and after looking at the actual source, it
does
initialize with only cents.
So, that means that I probably need to instantiate a Money object in the
view:
<%= text_field ... etc... Money.new(myvalue) %>

...,or, for every attribute in the model that does this composed_of:
def commission=(commission)
  Money.new(commission)
end

Is this the correct approach ?... or am I missing something ?
If this is correct, it would be great to add some of this to the docs !
59de94a56fd2c198f33d9515d1c05961?d=identicon&s=25 Tom Mornini (Guest)
on 2006-02-28 07:31
(Received via mailing list)
On Feb 27, 2006, at 8:35 PM, Dylan Stamat wrote:

> Hey Tom !  That does work... and after looking at the actual
> source, it does
> initialize with only cents. So, that means that I probably need to
> instantiate
> a Money object in the view:
> <%= text_field ... etc... Money.new (myvalue) %>

No, that should be totally unnecessary. Creating objects in a view is
a bad
practice in any case...

Get the money value into a non-db backed attribute...or the cents
attribute
since it's already around, then, upon form handling in the controller:

object = Object.new(params[:object])
object.commission = Money.new(object.cents)

The bottom line is this: when using composed_of, you must assign to it
with an object of the same class of the composed_of, which makes sense
when you think about it...

> ...,or, for every attribute in the model that does this composed_of:
> def commission=(commission)
>   Money.new(commission)
> end

That's cute! I sort of like it, but I doubt it's what you really
want, as
it will likely break the composed_of wizardly that allows you to set the
composed_of object in the first place... Perhaps you could name it:

   def set_commission(cents,currency='USD')
     commision = Money.new(cents,currency)
   end

Note the use of currency, and default of 'USD' (my favorite currency,
but
perhaps not yours, and perhaps not the best choice for your
application).
No reason to go through the work of implementing Money (a good idea!)
and
not wire it up so you can use the multi-currency functionality without a
lot of work later!

--
-- Tom Mornini
Ff82af3238a57fbd1212832ec1a19f28?d=identicon&s=25 Dylan Stamat (Guest)
on 2006-02-28 08:12
(Received via mailing list)
Great points Tom... and I am desperately trying to make my code less
cute :)

So, then there is no way I can just "create" the object when using
composed_of ?
model = MyModel.create(params[:mymodel])

So in my example, my Term model would actually need a non-model
"Commission"
value object lying around ?
59de94a56fd2c198f33d9515d1c05961?d=identicon&s=25 Tom Mornini (Guest)
on 2006-02-28 09:03
(Received via mailing list)
On Feb 27, 2006, at 11:11 PM, Dylan Stamat wrote:

> So, then there is no way I can just "create" the object when using
> composed_of ?
> model = MyModel. create(params[:mymodel])

Maybe not...you might well be able to set up something like in
MyModel...it's
your idea, after all! This code is untested...

# can a default be an attribute and/or method call?

def commission_cents=(cents,currency=self.currency)
   self.commission = Money.new(cents,currency)
end

And in the form:

<%= text_field 'Commission', :mymodel, :commission_cents %>
38a8230ed3d5c685558b4f0aad3fc74b?d=identicon&s=25 Joe Van Dyk (Guest)
on 2006-02-28 10:12
(Received via mailing list)
On 2/28/06, Tom Mornini <tmornini@infomania.com> wrote:
> # can a default be an attribute and/or method call?
>
> def commission_cents=(cents,currency=self.currency)
>   self.commission = Money.new(cents,currency)
> end
>
> And in the form:
>
> <%= text_field 'Commission', :mymodel, :commission_cents %>
>

Hm, here's what I have:

class Product
  composed_of :price, :class_name => Money, :mapping => [[:price,
:cents]]
  # other stuff
end

When I do (in my unit tests)
   p = Product.create
I get:
NoMethodError: You have a nil object when you didn't expect it!
The error occured while evaluating nil.round
        from
/usr/lib/ruby/gems/1.8/gems/money-1.7.1/lib/money/money.rb:52:in
`initialize'
        from (eval):3:in `price'

Any ideas?
59de94a56fd2c198f33d9515d1c05961?d=identicon&s=25 Tom Mornini (Guest)
on 2006-02-28 11:38
(Received via mailing list)
I'm pretty sure you cannot reuse the DB column name
for the composed_of value object.

--
-- Tom Mornini
Df040ca3576504b24a73744179903277?d=identicon&s=25 Tobias Lütke (Guest)
on 2006-02-28 15:27
(Received via mailing list)
your cents column needs to default to zero

On 2/28/06, Joe Van Dyk <joevandyk@gmail.com> wrote:
> >
>
> NoMethodError: You have a nil object when you didn't expect it!
>
--
Tobi
http://shopify.com       - modern e-commerce software
http://typo.leetsoft.com - Open source weblog engine
http://blog.leetsoft.com - Technical weblog
Df040ca3576504b24a73744179903277?d=identicon&s=25 Tobias Lütke (Guest)
on 2006-02-28 15:27
(Received via mailing list)
Are you running money 1.7.0 ?

On 2/27/06, Dylan Stamat <dylans@gmail.com> wrote:
> think), from the library.
>
> I must be overlooking something.  Any insight would be greatly appreciated !
>
> _______________________________________________
> Rails mailing list
> Rails@lists.rubyonrails.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>
>
>


--
Tobi
http://shopify.com       - modern e-commerce software
http://typo.leetsoft.com - Open source weblog engine
http://blog.leetsoft.com - Technical weblog
Ff82af3238a57fbd1212832ec1a19f28?d=identicon&s=25 Dylan Stamat (Guest)
on 2006-02-28 18:08
(Received via mailing list)
Thanks for popping in here Tobias :)   I'm running into a similar
problem as
Joe, and running 1.7.1.
38a8230ed3d5c685558b4f0aad3fc74b?d=identicon&s=25 Joe Van Dyk (Guest)
on 2006-02-28 21:06
(Received via mailing list)
On 2/28/06, Tobias Lütke <tobias.luetke@gmail.com> wrote:
> > > your idea, after all! This code is untested...
> > >
> > I get:
> > NoMethodError: You have a nil object when you didn't expect it!
> > The error occured while evaluating nil.round
> >         from /usr/lib/ruby/gems/1.8/gems/money-1.7.1/lib/money/money.rb:52:in
> > `initialize'
> >         from (eval):3:in `price'
> >
> > Any ideas?
>
> your cents column needs to default to zero

Ah, ok.  I didn't see that mentioned anywhere.  I'll try it tonight.

Is it ok to have a database column in my products table called
"price"?  Or does it need to be "cents"?
38a8230ed3d5c685558b4f0aad3fc74b?d=identicon&s=25 Joe Van Dyk (Guest)
on 2006-02-28 21:20
(Received via mailing list)
On 2/28/06, Joe Van Dyk <joevandyk@gmail.com> wrote:
> > > > MyModel...it's
> > > > <%= text_field 'Commission', :mymodel, :commission_cents %>
> > >    p = Product.create
>
> Ah, ok.  I didn't see that mentioned anywhere.  I'll try it tonight.
>
> Is it ok to have a database column in my products table called
> "price"?  Or does it need to be "cents"?

Yeah, I'm confused.  Do I do validations on "cents" (which is now a
database column in my products table) or on "price" (which is not a
database column anymore)?

 Here's part of my unit test for the Product class.  I'm having a lot
of troubles getting that to run correctly with the Money class and
composed_of.

  def test_that_product_has_to_have_a_price_greater_than_zero
    p = Product.create
    assert p.errors.on(:price)
    bad_prices = %w{ 0 asdf -10 40.OO }
    bad_prices.each do |bad_price|
      p.price = bad_price
      p.save
      assert p.errors.on(:price), "<#{ bad_price}> is apparently a good
price"
    end
    good_prices = %w{ 10 23.4 56.99 }
    good_prices.each do |price|
      p.price = price
      p.save
      assert_nil p.errors.on(:price)
    end
  end
This topic is locked and can not be replied to.