Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Allow monetizing methods with kwargs
- Fix money_only_cents for negative money
- Allow `super` when overriding methods

## 1.15.0

Expand Down
38 changes: 24 additions & 14 deletions lib/money-rails/active_record/monetizable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class ReadOnlyCurrencyException < MoneyRails::Error; end
extend ActiveSupport::Concern

module ClassMethods
MODULE_NAME = :DynamicMoneyAttributes

def monetized_attributes
monetized_attributes = @monetized_attributes || {}.with_indifferent_access

Expand Down Expand Up @@ -116,23 +118,31 @@ def monetize(*fields)
end
end


# Getter for monetized attribute
define_method name do |*args, **kwargs|
read_monetized name, subunit_name, options, *args, **kwargs
if const_defined?(MODULE_NAME, false)
mod = const_get(MODULE_NAME)
else
mod = const_set(MODULE_NAME, Module.new)
include mod
end

# Setter for monetized attribute
define_method "#{name}=" do |value|
write_monetized name, subunit_name, value, validation_enabled, instance_currency_name, options
end
mod.module_eval do
# Getter for monetized attribute
define_method name do |*args, **kwargs|
read_monetized name, subunit_name, options, *args, **kwargs
end

# Setter for monetized attribute
define_method "#{name}=" do |value|
write_monetized name, subunit_name, value, validation_enabled, instance_currency_name, options
end

if validation_enabled
# Ensure that the before_type_cast value is cleared when setting
# the subunit value directly
define_method "#{subunit_name}=" do |value|
instance_variable_set "@#{name}_money_before_type_cast", nil
write_attribute(subunit_name, value)
if validation_enabled
# Ensure that the before_type_cast value is cleared when setting
# the subunit value directly
define_method "#{subunit_name}=" do |value|
instance_variable_set "@#{name}_money_before_type_cast", nil
write_attribute(subunit_name, value)
end
end
end

Expand Down
17 changes: 17 additions & 0 deletions spec/active_record/monetizable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,23 @@ def update_product(*attributes)

context ".monetized_attributes" do

it "allows adds methods to the inheritance chain" do
class MyProduct < ActiveRecord::Base
self.table_name = :products
monetize :price_cents
attr_reader :side_effect

def price=(value)
@side_effect = true
super
end
end

p = MyProduct.new(price: 10)
expect(p.price).to eq Money.new(10_00)
expect(p.side_effect).to be_truthy
end

class InheritedMonetizeProduct < Product
monetize :special_price_cents
end
Expand Down