Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

increment_positions_on_lower_items called twice on insert_at with new item #21

Closed
demery opened this issue Nov 14, 2011 · 3 comments
Closed

Comments

@demery
Copy link

demery commented Nov 14, 2011

I found unexpected behavior when I call insert_at(position) on a new item (as is shown in the test_list.rb in the gem). If I insert a newly created (and not yet saved object), increment_positions_on_lower_items gets called twice, so that given positions [1,2], new_object.insert_at(2) results in positions [1,2,4].

See the following:

## GET THE PARENT
ruby-1.9.2-p290 :030 > shoot_list = ShootList.first
  ShootList Load (0.6ms)  SELECT "shoot_lists".* FROM "shoot_lists" LIMIT 1
 => #<ShootList id: 1, name: "xyx", manuscript_id: 1, lighting_config_id: nil, imaging_setup_id: nil, imaging_mode: nil, imaging_system_id: nil, created_at: "2011-11-11 22:26:39", updated_at: "2011-11-11 22:26:39"> 

### TWO ORDERED CHILDREN IN THE LIST
ruby-1.9.2-p290 :031 > shoot_list.shot_sequences.map(&:position)
  ShotSequence Load (0.7ms)  SELECT "shot_sequences".* FROM "shot_sequences" WHERE "shot_sequences"."shoot_list_id" = 1 ORDER BY position
 => [1, 2] 

## CREATE A NEW CHILD AND INSERT IT
ruby-1.9.2-p290 :032 > shot_sequence = ShotSequence.new(:subject => "elephant", :shoot_list => shoot_list)
 => #<ShotSequence id: nil, operator_instructions: nil, subject: "elephant", rotation_degrees: 0, position: nil, created_at: nil, updated_at: nil, shoot_list_id: 1> 
ruby-1.9.2-p290 :033 > shot_sequence.insert_at(2)
  SQL (2.2ms)  UPDATE "shot_sequences" SET position = (position + 1) WHERE ("shot_sequences"."shoot_list_id" = 1 AND position >= 2)
   (0.1ms)  BEGIN
  SQL (0.4ms)  UPDATE "shot_sequences" SET position = (position + 1) WHERE ("shot_sequences"."shoot_list_id" = 1 AND position >= 2)
  SQL (0.7ms)  INSERT INTO "shot_sequences" ("created_at", "operator_instructions", "position", "rotation_degrees", "shoot_list_id", "subject", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id"  [["created_at", Mon, 14 Nov 2011 12:34:05 EST -05:00], ["operator_instructions", nil], ["position", 2], ["rotation_degrees", 0], ["shoot_list_id", 1], ["subject", "elephant"], ["updated_at", Mon, 14 Nov 2011 12:34:05 EST -05:00]]
   (0.4ms)  COMMIT
 => true 

### RELOAD THE PARENT AND LIST THE CHILDREN
ruby-1.9.2-p290 :035 > shoot_list = ShootList.first
  ShootList Load (0.6ms)  SELECT "shoot_lists".* FROM "shoot_lists" LIMIT 1
 => #<ShootList id: 1, name: "xyx", manuscript_id: 1, lighting_config_id: nil, imaging_setup_id: nil, imaging_mode: nil, imaging_system_id: nil, created_at: "2011-11-11 22:26:39", updated_at: "2011-11-11 22:26:39"> 
ruby-1.9.2-p290 :036 > shoot_list.shot_sequences.map(&:position)
  ShotSequence Load (0.8ms)  SELECT "shot_sequences".* FROM "shot_sequences" WHERE "shot_sequences"."shoot_list_id" = 1 ORDER BY position
 => [1, 2, 4] 
ruby-1.9.2-p290 :037 > 

Note that two update calls are made to do the position increment. I stuck a backtrace printout in increment_positions_on_lower_items(position) and found the first call was made on insert and the second when the before_create callback is made.

Creating the item, and then inserting it in the correct position gets the desired result.

@swanandp
Copy link
Contributor

Hmm.. this is indeed weird. I have a feeling this was introduced during one of the recent pull requests. I am looking into this now, thanks for reporting!

@swanandp
Copy link
Contributor

The test test_insert_middle_with_unsaved_item addresses this issue and I think its fixed in the latest version. Can you please verify that it works for you?
Note: The latest version is not pushed to Rubygems yet.

@swanandp
Copy link
Contributor

This commit: f5bbea4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants