rails: When a parent model has `before/after_commit/rollback` hooks, changing child attributes with `accepts_nested_attributes_for` causes parent to not be touched
Steps to reproduce
Comment out line 39 after_commit { true }
to get all tests to pass:
begin
require "bundler/inline"
rescue LoadError => e
$stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler"
raise e
end
gemfile(true) do
source "https://rubygems.org"
gem "rails", github: "rails/rails"
gem "sqlite3"
end
require "active_record"
require "minitest/autorun"
require "logger"
# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :users do |t|
t.timestamps
end
create_table :posts do |t|
t.references :user
t.string :title
t.timestamps
end
end
class User < ActiveRecord::Base
has_many :posts
accepts_nested_attributes_for :posts
# Comment out to get tests to pass:
after_commit { true }
# Any of the following cause the same issue:
# after_rollback { true }
# before_commit { true }
# before_rollback { true }
end
class Post < ActiveRecord::Base
belongs_to :user, :touch => true
end
class BugTest < Minitest::Test
def setup
User.destroy_all
Post.destroy_all
# create a user that was updated an hour ago
user = User.create
user.update_columns :created_at => 1.hour.ago, :updated_at => 1.hour.ago
end
def test_creating_post_via_has_many_helper_touches_user
original_updated_at = User.first.updated_at
User.first.posts.create! :title => 'Post title'
refute_equal original_updated_at.to_i, User.first.updated_at.to_i
end
def test_creating_post_with_nested_attributes_touches_user
original_updated_at = User.first.updated_at
User.first.update! :posts_attributes => { '0' => { :title => 'Post title' } }
refute_equal original_updated_at.to_i, User.first.updated_at.to_i
end
end
Expected behavior
Creating/updating/destroying a child that is set to touch the parent should do so via nested attributes whether or not the parent has a before_commit
, after_commit
, before_rollback
or after_rollback
hook set.
Actual behavior
Creating a before_commit
, after_commit
, before_rollback
or after_rollback
hook causes nested attributes to NOT touch the parent, even though :touch => true
is set.
System configuration
Rails version: 5.0.0.1
Ruby version: 2.3.1
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 6
- Comments: 21 (12 by maintainers)
Commits related to this issue
- models: fix touch not propagating when using nested attributes Sometimes, when using nested attributes, touch doesn’t propagate to parent relationships. (see https://github.com/rails/rails/issues/267... — committed to demarches-simplifiees/demarches-simplifiees.fr by kemenaran 5 years ago
- models: fix touch not propagating when using nested attributes Sometimes, when using nested attributes, touch doesn’t propagate to parent relationships. (see https://github.com/rails/rails/issues/267... — committed to demarches-simplifiees/demarches-simplifiees.fr by kemenaran 5 years ago
- models: fix touch not propagating when using nested attributes Sometimes, when using nested attributes, touch doesn’t propagate to parent relationships. (see https://github.com/rails/rails/issues/267... — committed to demarches-simplifiees/demarches-simplifiees.fr by kemenaran 5 years ago
- models: fix touch not propagating when using nested attributes Sometimes, when using nested attributes, touch doesn’t propagate to parent relationships. (see https://github.com/rails/rails/issues/267... — committed to demarches-simplifiees/demarches-simplifiees.fr by kemenaran 5 years ago
- models: fix touch not propagating when using nested attributes Sometimes, when using nested attributes, touch doesn’t propagate to parent relationships. (see https://github.com/rails/rails/issues/267... — committed to demarches-simplifiees/demarches-simplifiees.fr by kemenaran 5 years ago
- models: fix touch not propagating when using nested attributes Sometimes, when using nested attributes, touch doesn’t propagate to parent relationships. (see https://github.com/rails/rails/issues/267... — committed to demarches-simplifiees/demarches-simplifiees.fr by kemenaran 5 years ago
- Fix caching issues with nested models Due to a Rails bug (https://github.com/rails/rails/issues/26726), cache is not correctly invalidated when updating child models. For example, if updating a produ... — committed to mrbrdo/spree by mrbrdo 2 years ago
- Fix caching issues with nested models Due to a Rails bug (https://github.com/rails/rails/issues/26726), cache is not correctly invalidated when updating child models. For example, if updating a produ... — committed to mrbrdo/spree by mrbrdo 2 years ago
- Execute the `before_committed!` callbacks on the most recent copy of the record Same as #36190 but for `before_committed!` callbacks. Before only the early copy of the same record (different object ... — committed to rails/rails by rafaelfranca 2 years ago
- Execute the `before_committed!` callbacks on the most recent copy of the record Same as #36190 but for `before_committed!` callbacks. Before only the early copy of the same record (different object ... — committed to rails/rails by rafaelfranca 2 years ago
- Fix caching issues with nested models Due to a Rails bug (https://github.com/rails/rails/issues/26726), cache is not correctly invalidated when updating child models. For example, if updating a produ... — committed to mrbrdo/spree by mrbrdo 2 years ago
- Fix caching issues with nested models Due to a Rails bug (https://github.com/rails/rails/issues/26726), cache is not correctly invalidated when updating child models. For example, if updating a produ... — committed to mrbrdo/spree by mrbrdo 2 years ago
- Fix caching issues with nested models Due to a Rails bug (https://github.com/rails/rails/issues/26726), cache is not correctly invalidated when updating child models. For example, if updating a produ... — committed to mrbrdo/spree by mrbrdo 2 years ago
- Fix caching issues with nested models Due to a Rails bug (https://github.com/rails/rails/issues/26726), cache is not correctly invalidated when updating child models. For example, if updating a produ... — committed to mrbrdo/spree by mrbrdo 2 years ago
When working on circumventing the bug by adding
after_save
callbacks as proposed by @cannikin, the test I was writing turned green when I added theinverse_of
option on thehas_many
association. Manual tests confirmed that adding the option leads to the desired behaviour.In the example provided, this would translate to
The option seems to ensure the correct instance for the touch.
Just housekeeping. If this is an issue for you, please go ahead and submit a PR. This isn’t an issue for our applications, so of course we are not going to prioritize it.
@eileencodes what do you mean they don’t have a modern reproduction? I assume Minitest still exists? I will be happy to make it more modern for you if you explain what you need. This issue was tagged and assigned 6 years ago but was never fixed or attempted to be fixed. The author of the offending code was tagged but has not responded. I’m quite busy too, believe it or not.
@ulferts nice find! thanks! It’s a much better work around, because
after_save
callbacks are called multiple times, e.g. in the example above when you update multiple posts throughaccepts_nested_attributes_for
on the same user, the belonging user gets touched multiple times. Withinverse_of
all posts updates are run, then the belonging user gets touched once.