diff --git a/README.md b/README.md index bbf4be7c..0d2fbd4e 100644 --- a/README.md +++ b/README.md @@ -337,6 +337,8 @@ end **Important:** If you use connection pooling (e.g., PgBouncer), using `.with_meta` without a transaction may lead to unexpected results (since meta is set for a connection). Without a transaction, we cannot guarantee that the same connection will be used for queries (including metadata cleanup). +**Important**: In Rails, `after_commit` callbacks are executed after transaction is committed, and, thus, after `with_meta` block is executed—the meta wouldn't be added to changes captured in the `after_commit` phase. One particular scenario is having associations with `touch: true` (_touch_ updates are executed after commit). + ### Track responsibility A special application of meta information is storing the author of the change, which is called _Responsible ID_. There is more likely that you would like to store the `current_user.id` that way. diff --git a/spec/dummy/app/models/article.rb b/spec/dummy/app/models/article.rb index 0a38fdba..bb89651f 100644 --- a/spec/dummy/app/models/article.rb +++ b/spec/dummy/app/models/article.rb @@ -3,6 +3,6 @@ class Article < ActiveRecord::Base has_logidze - belongs_to :user, optional: true + belongs_to :user, optional: true, touch: :time has_many :comments end diff --git a/spec/integration/meta_spec.rb b/spec/integration/meta_spec.rb index 0197bae5..3d3da2a6 100644 --- a/spec/integration/meta_spec.rb +++ b/spec/integration/meta_spec.rb @@ -20,7 +20,7 @@ let(:meta2) { {"other_key" => "other_val"} } describe ".with_meta" do - subject { User.create!(name: "test", age: 10, active: false) } + subject(:user) { User.create!(name: "test", age: 10, active: false) } context "insert" do it "doesn't set meta if it's not provided" do @@ -209,6 +209,19 @@ expect(subject.at_version(2)).to be_nil expect(subject.at_version(3).meta).to eq meta2 end + + # See https://github.com/palkan/logidze/issues/236 + context "with Rails touch:true" do + let!(:article) { Article.create!(title: "test", user: user) } + + it "updating a record updates the parent record's log_data with the correct meta" do + Logidze.with_meta(meta, transactional: false) do + article.touch(time: 1.minute.since) + end + + expect(user.reload.log_data.meta).to eq(meta) + end + end end context "when transactional:false" do diff --git a/spec/support/acceptance_helpers.rb b/spec/support/acceptance_helpers.rb index 1c0978d5..b4288253 100644 --- a/spec/support/acceptance_helpers.rb +++ b/spec/support/acceptance_helpers.rb @@ -32,7 +32,7 @@ def run_command(cmd, env: {}, success: true) ) if ENV["LOG"] - puts "\n\nCOMMAND:\n#{command}\n\nOUTPUT:\n#{output}\nERROR:\n#{err}\n" + puts "\n\nCOMMAND:\n#{cmd}\n\nOUTPUT:\n#{output}\nERROR:\n#{err}\n" end [status, output, err]