brendon / acts_as_list

An ActiveRecord plugin for managing lists.
http://brendon.github.io/acts_as_list/
MIT License
2.05k stars 356 forks source link

Is it possible to have items belong to multiple lists? #324

Closed cibernox closed 5 months ago

cibernox commented 6 years ago

This wasn't clear from the documentation.

I have some items that belongs to two separate lists. Within list A, one item can be on the second position, but within list B, that same record can be the first item.

I thought that the model could have two columns position_1 and position_2, and thus be able to operate with them, but seems by the method names that they only operate over one list.

brendon commented 6 years ago

Hi @cibernox, I'm not 100% sure we support that currently. You can define what the position column is but I don't know if you can have more than one acts_as_list declaration per model. Is it something you could work around with scopes instead?

Otherwise, take a look at ranked_model as that supports multiple ranks.

oyeanuj commented 4 years ago

@brendon Quick follow-up to this old issue. My use-case, simplified, is I have a list of items that can be either published or un-published. The owner can be shown both merged, or un-merged (so, either published or unpublished). I'm curious about position collisions and expected behavior, moving an item from unpublished to published.

In such a scenario, would you recommend ranked_model over acts_as_list? If so, are there any other migration guides/tips/steps to move between the two?

brendon commented 4 years ago

Hi @oyeanuj, acts_as_list should be able to handle this with scopes. The scope can be the column that defines if the item is published or unpublished. However if that column is on another table then that probably won't work.

I don't think ranked_model supports off-table scopes either. Both libraries should handle position collisions fairly well, though ranked_model is probably more fault tolerant due to how it stores sparse positions. Someone recently added some documentation to ranked_model README for migrating an existing table, you could adapt this I think :)

My advice would be to stick with acts_as_list until you're sure it can't do what you want. Feel free to ask any more questions :D

oyeanuj commented 4 years ago

@brendon Got it, that makes sense! My scope column is in the same table, so I'll give it a run. acts_as_list is also more familiar which sometimes matters as much as well :)

pyrat commented 3 years ago

I found a working solution here. You can extend the base class and override the acts_as_list. eg.

class Snippet < ApplicationRecord
  acts_as_list scope: [:title_id, :object_type, { cue_in: -1 }]
end

class AllSnippet < Snippet
  acts_as_list scope: [:title_id, { cue_in: -1 }], column: :title_position
end

@snippet = AllSnippet.find params[:id]
@snippet.insert_at(params[:position]) # will update the title_position
oyeanuj commented 2 years ago

@brendon Back again on this issue as I've hit an issue with a use-case similar to the original ask by @cibernox. Here is a simplified version of the use-case.

Say, you have models called Member and Group wherein Members belong to Groups. We need to:

Now, it seems most intuitive to me that on GroupMembership table to have member_position_in_group and group_position_for_member columns and for those to be individual acts_as_list column

class GroupMembership < ApplicationRecord

  belongs_to :member
  belongs_to :group

  acts_as_list scope:member_position_in_group
  acts_as_list scope:group_position_for_member

end 

GroupMembership.find(10).move_to_top(:member_position_in_group) #Moves to the top position for that column

Thoughts?

brendon commented 2 years ago

Hi @oyeanuj, that does make a lot of sense. I think the problem is that this gem was written with the assumption of a single column per table for storing position. It's not ideal unfortunately. There are so many assumptions around this in the code that it'd take quite a big refactor to fix. If you want to have a go at it I'd be happy to review what you've done but part of me feels like it's time to write something from scratch. I've been toying with a concern for this purpose. It still assumes a single column, but perhaps it could be easier to rework this smaller codebase. https://gist.github.com/brendon/d6cfd60cb5e70dc77a15a2476f04d279

oyeanuj commented 2 years ago

@brendon thanks for that quick response! unfortunately, my ruby skills aren't good enough to feel confident on taking on a refactor. thanks for sharing that gist though, I'll look more into it!

brendon commented 2 years ago

No worries man. Yea it's a complicated code base (and in some cases unnecessarily so).

brendon commented 5 months ago

Just a quick note to say you should be able to do this with my new gem: https://github.com/brendon/positioning

If you do end up switching to that, let me know if you need any help.