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

Added Functionality for Repairing Duplicate Positions in List #335

Closed

Conversation

pacarvalho
Copy link

closes #333

@pacarvalho
Copy link
Author

pacarvalho commented Jan 1, 2019

@brendon I am still working on this PR but I put it here so that you can have a look and let me know if this is what you had in mind.

I still need to write the functions and checks for gaps in the list, improve tests and write documentation.

I might also add a protection to impede the function from getting stuck in the while look... Just not sure if it makes sense...

Copy link
Owner

@brendon brendon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A good start @pacarvalho :) Let me know once you added some more.

# Checks if a list has no repeating indices
# Returns true if at least one value position_column has a duplicate value
def does_list_have_duplicates?
acts_as_list_class.group(position_column).having("count(?) > 1", position_column).any?
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be .exists? instead of .any? I think (off the top of my head).

# While there are duplicates we will increment the position of the second repetition for every number
while does_list_have_duplicates? do
# Get the position with repetitions
repeated_pos = acts_as_list_class.group(position_column).having("count(?) > 1", position_column).first.send(position_column)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you're using acts_as_list_class.group(position_column).having("count(?) > 1", position_column) more than one, you should probably make it a scope on the mode and give it a friendly name :)

# Get the position with repetitions
repeated_pos = acts_as_list_class.group(position_column).having("count(?) > 1", position_column).first.send(position_column)
# Get one of the entries in the given position. This will be the entry that will keep the current position
first_repeated_entry_id = acts_as_list_class.where("#{position_column} >= ?", repeated_pos).first.id
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be = not >=? And if so, you can simplify the where call to remove the string interpolation :)

end
end

# Check that there are no gaps in the list
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking forward to what you come up with here :)

# Get one of the entries in the given position. This will be the entry that will keep the current position
first_repeated_entry_id = acts_as_list_class.where("#{position_column} >= ?", repeated_pos).first.id
# Increment the position of all entries with position equal or greater than the current repeted position that is not the first entry
acts_as_list_class.where("#{position_column} >= ?", repeated_pos).where.not(id: first_repeated_entry_id).increment_all
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When interpolating the position column use quoted_position_column_with_table_name as per list.rb.

assert_equal true, DefaultScopedMixin.first.does_list_have_duplicates?

# Fix the list
DefaultScopedMixin.first.repair_duplicate_positions_in_list
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the repair code would be better attached to the class rather than the instance. We can still call it from the instance.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be DefaultScopedMixin.repair_duplicate_positions_in_list(DefaultScopedMixin.first) instead?

…osition_column_with_table_name, removed mention of detecting gaps
@pacarvalho pacarvalho changed the title Added Functionality for Repairing List [WIP DO NOT MERGE] Added Functionality for Repairing List Jun 15, 2019
@pacarvalho pacarvalho changed the title Added Functionality for Repairing List Added Functionality for Repairing Duplicate Positions in List Jun 15, 2019
@brendon
Copy link
Owner

brendon commented Sep 1, 2019

I'm still interested in adding this. Also see https://github.com/swanandp/acts_as_list/pull/284/files which I've closed but had a test for detecting corrupted lists. Perhaps we could add an auto-correct option (off by default)?

@oyeanuj
Copy link

oyeanuj commented Apr 12, 2020

@pacarvalho Is this still on your radar?

@pacarvalho
Copy link
Author

@oyeanuj I am interested in seeing this completed. Just need to know what needs to be changed/added. It has been a while since I started this so I don't quite remember where we left off :/

Are you interested in collaborating?

@brendon
Copy link
Owner

brendon commented Apr 13, 2020

I'm happy to review what you guys come up with. I think the overarching goal of any auto-correction would be for it to be completely transparent to the user (and with no side effects). Since it'll likely happen at the time a change is being made to the list, this could get messy as if positions of items change from what the user was expecting, their intentions could become invalid.

I might have the wrong end of the stick however, it's been a long time since I looked at this :D

@oyeanuj
Copy link

oyeanuj commented Apr 13, 2020

@brendon @pacarvalho Thanks for the quick responses! I honestly don't understand the code enough (or for that matter Rails), to be able to come up with a sufficiently competent PR. Mostly, I was curious if I should be expecting this PR to this library or not :)

@brendon
Copy link
Owner

brendon commented Jun 3, 2024

Closing this as it's been 4 years. Check out https://github.com/brendon/positioning as an alternative that does its best to avoid list corruption. It works with database uniqueness constraints and advisory locks to prevent these kinds of issues.

@brendon brendon closed this Jun 3, 2024
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

Successfully merging this pull request may close these issues.

Can I Create a PR with a Function that "Fixes" List in Case of Duplicates?
3 participants