Module: MoneyRails::ActiveRecord::Monetizable
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/money-rails/active_record/monetizable.rb
Defined Under Namespace
Modules: ClassMethods Classes: ReadOnlyCurrencyException
Instance Method Summary collapse
- #currency_for(name, instance_currency_name, field_currency_name) ⇒ Object
- #read_monetized(name, subunit_name, options = {}, *args) ⇒ Object
- #write_monetized(name, subunit_name, value, validation_enabled, instance_currency_name, options) ⇒ Object
Instance Method Details
#currency_for(name, instance_currency_name, field_currency_name) ⇒ Object
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/money-rails/active_record/monetizable.rb', line 277 def currency_for(name, instance_currency_name, field_currency_name) if instance_currency_name.present? && respond_to?(instance_currency_name) && Money::Currency.find(public_send(instance_currency_name)) Money::Currency.find(public_send(instance_currency_name)) elsif field_currency_name.respond_to?(:call) Money::Currency.find(field_currency_name.call(self)) elsif field_currency_name Money::Currency.find(field_currency_name) elsif self.class.respond_to?(:currency) self.class.currency else Money.default_currency end end |
#read_monetized(name, subunit_name, options = {}, *args) ⇒ Object
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/money-rails/active_record/monetizable.rb', line 181 def read_monetized(name, subunit_name, = {}, *args) # Get the cents amount = public_send(subunit_name, *args) return if amount.nil? && [:allow_nil] # Get the currency object attr_currency = public_send("currency_for_#{name}") # Get the cached value memoized = instance_variable_get("@#{name}") # Dont create a new Money instance if the values haven't been changed. if memoized && memoized.cents == amount if memoized.currency == attr_currency result = memoized else memoized_amount = memoized.amount.to_money(attr_currency) write_attribute subunit_name, memoized_amount.cents # Cache the value (it may be nil) result = instance_variable_set("@#{name}", memoized_amount) end elsif amount.present? # If amount is NOT nil (or empty string) load the amount in a Money amount = Money.new(amount, attr_currency) # Cache the value (it may be nil) result = instance_variable_set("@#{name}", amount) end if MoneyRails::Configuration.preserve_user_input value_before_type_cast = instance_variable_get "@#{name}_money_before_type_cast" if errors.has_key?(name.to_sym) result.define_singleton_method(:to_s) { value_before_type_cast } result.define_singleton_method(:format) { |_| value_before_type_cast } end end result end |
#write_monetized(name, subunit_name, value, validation_enabled, instance_currency_name, options) ⇒ Object
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
# File 'lib/money-rails/active_record/monetizable.rb', line 221 def write_monetized(name, subunit_name, value, validation_enabled, instance_currency_name, ) # Keep before_type_cast value as a reference to original input instance_variable_set "@#{name}_money_before_type_cast", value # Use nil or get a Money object if [:allow_nil] && value.blank? money = nil else if value.is_a?(Money) money = value else begin money = value.to_money(public_send("currency_for_#{name}")) rescue NoMethodError return nil rescue Money::Currency::UnknownCurrency, Monetize::ParseError => e raise MoneyRails::Error, e. if MoneyRails.raise_error_on_money_parsing return nil end end end # Update cents if !validation_enabled # We haven't defined our own subunit writer, so we can invoke # the regular writer, which works with store_accessors public_send("#{subunit_name}=", money.try(:cents)) elsif self.class.respond_to?(:attribute_aliases) && self.class.attribute_aliases.key?(subunit_name) # If the attribute is aliased, make sure we write to the original # attribute name or an error will be raised. # (Note: 'attribute_aliases' doesn't exist in Rails 3.x, so we # can't tell if the attribute was aliased.) original_name = self.class.attribute_aliases[subunit_name.to_s] write_attribute(original_name, money.try(:cents)) else write_attribute(subunit_name, money.try(:cents)) end if money_currency = money.try(:currency) # Update currency iso value if there is an instance currency attribute if instance_currency_name.present? && respond_to?("#{instance_currency_name}=") public_send("#{instance_currency_name}=", money_currency.iso_code) else current_currency = public_send("currency_for_#{name}") if current_currency != money_currency.id raise ReadOnlyCurrencyException.new("Can't change readonly currency '#{current_currency}' to '#{money_currency}' for field '#{name}'") if MoneyRails.raise_error_on_money_parsing return nil end end end # Save and return the new Money object instance_variable_set "@#{name}", money end |