From 8009b3772319004d2ae67869f58dff49b9d4ecee Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 3 Nov 2022 13:01:02 +1100 Subject: [PATCH 1/2] Spec the AddressSerializer before changing it --- .../api/address_serializer_spec.rb | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 spec/serializers/api/address_serializer_spec.rb diff --git a/spec/serializers/api/address_serializer_spec.rb b/spec/serializers/api/address_serializer_spec.rb new file mode 100644 index 0000000000..96ffa9fec7 --- /dev/null +++ b/spec/serializers/api/address_serializer_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Api::AddressSerializer do + subject(:serializer) { described_class.new(address) } + let(:address) { build(:address) } + + describe "#country_name" do + it "provides the country's name" do + address.country.name = "Australia" + expect(serializer.country_name).to eq "Australia" + end + end + + describe "#state_name" do + it "provides the state's abbreviation" do + address.state.abbr = "Vic" + expect(serializer.state_name).to eq "Vic" + end + end + + describe "caching" do + it "updates with the record" do + expect { + address.update!(first_name: "Nick") + }.to change { + serializer.to_json + } + end + + it "updates even when database wasn't changed" do + expect { + address.first_name = "Nick" + }.to change { + serializer.to_json + } + end + end +end From 118c1f7cbd89715af0066e8ea21d69aaef8795de Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 3 Nov 2022 13:02:12 +1100 Subject: [PATCH 2/2] Cache address JSON to avoid database queries We found that our database is quite busy querying the country all the time. One source of these queries is the shop front which serializes enterprises including their addresses. But addresses should be safe to cache because: - country records never change - state records never change - updating any other attribute changes the cache key The caching was previously removed when the state_name attribute was added. That is technically correct because it's possible to change a state's name without updating the address. Then the cache would be out of date. But we never update state names. And if we did, we would need to invalidate the cache now. --- app/serializers/api/address_serializer.rb | 4 ++-- spec/serializers/api/address_serializer_spec.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/serializers/api/address_serializer.rb b/app/serializers/api/address_serializer.rb index 6edbc6adc9..4c1c3e6c3f 100644 --- a/app/serializers/api/address_serializer.rb +++ b/app/serializers/api/address_serializer.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true class Api::AddressSerializer < ActiveModel::Serializer - # cached - # delegate :cache_key, to: :object + cached + delegate :cache_key, to: :object attributes :id, :zipcode, :city, :state_name, :state_id, :phone, :firstname, :lastname, :address1, :address2, :city, :country_id, diff --git a/spec/serializers/api/address_serializer_spec.rb b/spec/serializers/api/address_serializer_spec.rb index 96ffa9fec7..9ebbfcd2d7 100644 --- a/spec/serializers/api/address_serializer_spec.rb +++ b/spec/serializers/api/address_serializer_spec.rb @@ -29,10 +29,10 @@ describe Api::AddressSerializer do } end - it "updates even when database wasn't changed" do + it "uses stored result when database wasn't changed" do expect { address.first_name = "Nick" - }.to change { + }.to_not change { serializer.to_json } end