Skip to content

Commit

Permalink
Don't update a child destroyed via relation (#261)
Browse files Browse the repository at this point in the history
  • Loading branch information
brendon committed Mar 13, 2017
1 parent 1f6175d commit 64c9438
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 3 deletions.
1 change: 1 addition & 0 deletions Gemfile
Expand Up @@ -12,6 +12,7 @@ group :test do
gem "minitest", "~> 5.0"
gem "test_after_commit", "~> 0.4.2"
gem "timecop"
gem "mocha"
end

group :sqlite do
Expand Down
1 change: 1 addition & 0 deletions gemfiles/rails_3_2.gemfile
Expand Up @@ -12,6 +12,7 @@ group :test do
gem "minitest", "~> 5.0"
gem "test_after_commit", "~> 0.4.2"
gem "timecop"
gem "mocha"
gem "after_commit_exception_notification"
end

Expand Down
1 change: 1 addition & 0 deletions gemfiles/rails_4_1.gemfile
Expand Up @@ -12,6 +12,7 @@ group :test do
gem "minitest", "~> 5.0"
gem "test_after_commit", "~> 0.4.2"
gem "timecop"
gem "mocha"
gem "after_commit_exception_notification"
end

Expand Down
1 change: 1 addition & 0 deletions gemfiles/rails_4_2.gemfile
Expand Up @@ -12,6 +12,7 @@ group :test do
gem "minitest", "~> 5.0"
gem "test_after_commit", "~> 0.4.2"
gem "timecop"
gem "mocha"
end

group :sqlite do
Expand Down
1 change: 1 addition & 0 deletions gemfiles/rails_5_0.gemfile
Expand Up @@ -12,6 +12,7 @@ group :test do
gem "minitest", "~> 5.0"
gem "test_after_commit", "~> 0.4.2"
gem "timecop"
gem "mocha"
end

group :sqlite do
Expand Down
1 change: 1 addition & 0 deletions gemfiles/rails_5_1.gemfile
Expand Up @@ -12,6 +12,7 @@ group :test do
gem "minitest", "~> 5.0"
gem "test_after_commit", "~> 0.4.2"
gem "timecop"
gem "mocha"
end

group :sqlite do
Expand Down
4 changes: 2 additions & 2 deletions lib/acts_as_list/active_record/acts/callback_definer.rb
Expand Up @@ -3,8 +3,8 @@ def self.call(caller_class, add_new_at)
caller_class.class_eval do
before_validation :check_top_position, unless: :act_as_list_no_update?

before_destroy :lock!
after_destroy :decrement_positions_on_lower_items, unless: :act_as_list_no_update?
before_destroy :lock!, unless: "destroyed_via_scope? || act_as_list_no_update?"
after_destroy :decrement_positions_on_lower_items, unless: "destroyed_via_scope? || act_as_list_no_update?"

This comment has been minimized.

Copy link
@CvX

CvX Mar 16, 2017

Contributor

That's another Rails 5.1 deprecation:

DEPRECATION WARNING: Passing string to :if and :unless conditional options is deprecated and will be removed in Rails 5.2 without replacement.

This comment has been minimized.

Copy link
@brendon

brendon Mar 16, 2017

Author Owner

Egad! I guess we can just make it into a method instead.


before_update :check_scope, unless: :act_as_list_no_update?
after_update :update_positions, unless: :act_as_list_no_update?
Expand Down
14 changes: 14 additions & 0 deletions lib/acts_as_list/active_record/acts/scope_method_definer.rb
Expand Up @@ -17,6 +17,11 @@ def self.call(caller_class, scope)
define_method :scope_changed? do
changed.include?(scope_name.to_s)
end

define_method :destroyed_via_scope? do
return false if ActiveRecord::VERSION::MAJOR < 4
scope == (destroyed_by_association && destroyed_by_association.foreign_key.to_sym)
end
elsif scope.is_a?(Array)
define_method :scope_condition do
scope.inject({}) do |hash, column|
Expand All @@ -27,6 +32,11 @@ def self.call(caller_class, scope)
define_method :scope_changed? do
(scope_condition.keys & changed.map(&:to_sym)).any?
end

define_method :destroyed_via_scope? do
return false if ActiveRecord::VERSION::MAJOR < 4
scope_condition.keys.include? (destroyed_by_association && destroyed_by_association.foreign_key.to_sym)
end
else
define_method :scope_condition do
eval "%{#{scope}}"
Expand All @@ -35,6 +45,10 @@ def self.call(caller_class, scope)
define_method :scope_changed? do
false
end

define_method :destroyed_via_scope? do
false
end
end

self.scope :in_list, lambda { where("#{quoted_position_column_with_table_name} IS NOT NULL") }
Expand Down
1 change: 1 addition & 0 deletions test/helper.rb
Expand Up @@ -11,6 +11,7 @@
end
require "active_record"
require "minitest/autorun"
require "mocha/mini_test"
require "#{File.dirname(__FILE__)}/../init"

if defined?(ActiveRecord::VERSION) &&
Expand Down
2 changes: 1 addition & 1 deletion test/test_no_update_for_extra_classes.rb
Expand Up @@ -33,7 +33,7 @@ def setup
end

ActiveRecord::Base.connection.schema_cache.clear!
[TodoList, Item, TodoItemAttachment].each(&:reset_column_information)
[TodoList, TodoItem, TodoItemAttachment].each(&:reset_column_information)
super
end

Expand Down
72 changes: 72 additions & 0 deletions test/test_no_update_for_scope_destruction.rb
@@ -0,0 +1,72 @@
require 'helper'

class DestructionTodoList < ActiveRecord::Base
has_many :destruction_todo_items, dependent: :destroy
has_many :destruction_tada_items, dependent: :destroy
end

class DestructionTodoItem < ActiveRecord::Base
belongs_to :destruction_todo_list
acts_as_list scope: :destruction_todo_list
end

class DestructionTadaItem < ActiveRecord::Base
belongs_to :destruction_todo_list
acts_as_list scope: [:destruction_todo_list_id, :enabled]
end

class NoUpdateForScopeDestructionTestCase < Minitest::Test
def setup
ActiveRecord::Base.connection.create_table :destruction_todo_lists do |t|
end

ActiveRecord::Base.connection.create_table :destruction_todo_items do |t|
t.column :position, :integer
t.column :destruction_todo_list_id, :integer
end

ActiveRecord::Base.connection.create_table :destruction_tada_items do |t|
t.column :position, :integer
t.column :destruction_todo_list_id, :integer
t.column :enabled, :boolean
end

ActiveRecord::Base.connection.schema_cache.clear!
[DestructionTodoList, DestructionTodoItem, DestructionTadaItem].each(&:reset_column_information)
super
end

def teardown
teardown_db
super
end

class NoUpdateForScopeDestructionTest < NoUpdateForScopeDestructionTestCase
def setup
super
@list = DestructionTodoList.create!

@todo_item_1 = DestructionTodoItem.create! position: 1, destruction_todo_list_id: @list.id
@tada_item_1 = DestructionTadaItem.create! position: 1, destruction_todo_list_id: @list.id, enabled: true
end

def test_no_update_children_when_parent_destroyed
if ActiveRecord::VERSION::MAJOR < 4
DestructionTodoItem.any_instance.expects(:decrement_positions_on_lower_items).once
DestructionTadaItem.any_instance.expects(:decrement_positions_on_lower_items).once
else
DestructionTodoItem.any_instance.expects(:decrement_positions_on_lower_items).never
DestructionTadaItem.any_instance.expects(:decrement_positions_on_lower_items).never
end
assert @list.destroy
end

def test_update_children_when_sibling_destroyed
@todo_item_1.expects(:decrement_positions_on_lower_items).once
@tada_item_1.expects(:decrement_positions_on_lower_items).once
assert @todo_item_1.destroy
assert @tada_item_1.destroy
end

end
end

0 comments on commit 64c9438

Please sign in to comment.