Skip to content

Commit

Permalink
Make currency_column and a static currency explicit arguments ins…
Browse files Browse the repository at this point in the history
…tead of switching on argument type
  • Loading branch information
Bart de Water committed Jul 31, 2017
1 parent 19c3848 commit d6e892f
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 12 deletions.
12 changes: 7 additions & 5 deletions README.md
Expand Up @@ -132,11 +132,13 @@ Order.where(sub_total: Money.new(9.99, 'CAD'))
```

`money_column` uses an attribute called 'currency' by default. This can be
overridden by supplying a symbol for the column name, e.g.:
`currency: :other_column`. If your currency is hardcoded and there is no
column, supply the currency code as a string instead. You can use multiple
`money_column` calls to achieve the desired effects with currency on the model
or attribute level.
overridden by supplying another column name, e.g.: `currency_column: :other`.
If your currency is hardcoded and there is no column, set a falsey currency
column and supply the currency code instead:
`money_column :price_usd, currency_column: false, currency: 'USD'`

You can use multiple `money_column` calls to achieve the desired effects with
currency on the model or attribute level.

There are no validations generated. You can add these for the specified money
and currency attributes as you normally would for any other.
Expand Down
13 changes: 8 additions & 5 deletions lib/money_column/active_record_hooks.rb
Expand Up @@ -5,18 +5,19 @@ def self.included(base)
end

module ClassMethods
def money_column(*columns, currency: :currency)
columns = columns.flatten
def money_column(*columns, currency_column: :currency, currency: false)
raise ArgumentError, 'cannot set both currency_column and a fixed currency' if currency_column && currency

if currency.is_a?(Symbol)
columns = columns.flatten
if currency_column
columns.each do |column|
composed_of(
column.to_sym,
class_name: 'Money',
mapping: [[column.to_s, 'value'], [currency.to_s, 'currency']]
mapping: [[column.to_s, 'value'], [currency_column.to_s, 'currency']]
)
end
else
elsif currency
columns.each do |column|
composed_of(
column.to_sym,
Expand All @@ -25,6 +26,8 @@ def money_column(*columns, currency: :currency)
constructor: proc { |value| Money.new(value, currency) }
)
end
else
raise ArgumentError, 'need to set either currency_column or currency'
end
end
end
Expand Down
30 changes: 28 additions & 2 deletions spec/money_column_spec.rb
Expand Up @@ -7,8 +7,8 @@ class MoneyRecord < ActiveRecord::Base
end

money_column :price
money_column :prix, currency: :devise
money_column :price_usd, currency: 'USD'
money_column :prix, currency_column: :devise
money_column :price_usd, currency_column: false, currency: 'USD'
end

class MoneyWithValidation < ActiveRecord::Base
Expand Down Expand Up @@ -72,6 +72,32 @@ class MoneyWithValidation < ActiveRecord::Base
end
end

describe 'wrong money_column currency arguments' do
let(:subject) do
class MoneyWithWrongCurrencyArguments < ActiveRecord::Base
self.table_name = 'money_records'
money_column :price, currency_column: :currency, currency: 'USD'
end
end

it 'raises an ArgumentError' do
expect { subject }.to raise_error(ArgumentError, 'cannot set both currency_column and a fixed currency')
end
end

describe 'missing money_column currency arguments' do
let(:subject) do
class MoneyWithMissingCurrencyArguments < ActiveRecord::Base
self.table_name = 'money_records'
money_column :price, currency_column: false, currency: false
end
end

it 'raises an ArgumentError' do
expect { subject }.to raise_error(ArgumentError, 'need to set either currency_column or currency')
end
end

describe 'null currency and validations' do
let(:currency) { Money::NullCurrency.new }
let(:subject) { MoneyWithValidation.new(price: money) }
Expand Down

0 comments on commit d6e892f

Please sign in to comment.