diff --git a/lib/money.rb b/lib/money.rb index acaaeeff..5335e7f9 100644 --- a/lib/money.rb +++ b/lib/money.rb @@ -12,5 +12,6 @@ require_relative 'money/accounting_money_parser' require_relative 'money/core_extensions' require_relative 'money_column' if defined?(ActiveRecord) +require_relative 'money/railtie' if defined?(Rails::Railtie) require_relative 'rubocop/cop/money' if defined?(RuboCop) diff --git a/lib/money/rails/job_argument_serializer.rb b/lib/money/rails/job_argument_serializer.rb new file mode 100644 index 00000000..3f074d70 --- /dev/null +++ b/lib/money/rails/job_argument_serializer.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class Money + module Rails + class JobArgumentSerializer < ::ActiveJob::Serializers::ObjectSerializer + def serialize(money) + super("value" => money.value, "currency" => money.currency.iso_code) + end + + def deserialize(hash) + Money.new(hash["value"], hash["currency"]) + end + + private + + def klass + Money + end + end + end +end + diff --git a/lib/money/railtie.rb b/lib/money/railtie.rb new file mode 100644 index 00000000..81149592 --- /dev/null +++ b/lib/money/railtie.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class Money + class Railtie < Rails::Railtie + initializer "shopify-money.setup_active_job_serializer" do + ActiveSupport.on_load :active_job do + require_relative "rails/job_argument_serializer" + ActiveJob::Serializers.add_serializers ::Money::Rails::JobArgumentSerializer + end + end + end +end diff --git a/spec/rails/job_argument_serializer_spec.rb b/spec/rails/job_argument_serializer_spec.rb new file mode 100644 index 00000000..a1c35249 --- /dev/null +++ b/spec/rails/job_argument_serializer_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require "rails_spec_helper" + +RSpec.describe Money::Rails::JobArgumentSerializer do + it "roundtrip a Money argument returns the same object" do + job = MoneyTestJob.new(value: Money.new(10.21, "BRL")) + + serialized_job = job.serialize + serialized_value = serialized_job["arguments"][0]["value"] + expect(serialized_value["_aj_serialized"]).to eq("Money::Rails::JobArgumentSerializer") + expect(serialized_value["value"]).to eq(BigDecimal("10.21")) + expect(serialized_value["currency"]).to eq("BRL") + + job2 = MoneyTestJob.deserialize(serialized_job) + job2.send(:deserialize_arguments_if_needed) + + expect(job2.arguments.first[:value]).to eq(Money.new(10.21, "BRL")) + end +end diff --git a/spec/rails_spec_helper.rb b/spec/rails_spec_helper.rb new file mode 100644 index 00000000..bb8e4fe9 --- /dev/null +++ b/spec/rails_spec_helper.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require "active_job" +require_relative "spec_helper" + +Money::Railtie.initializers.each(&:run) + +class MoneyTestJob < ActiveJob::Base + def perform(_params) + end +end