acts_as_list icon indicating copy to clipboard operation
acts_as_list copied to clipboard

Is it possible to have items belong to multiple lists?

Open cibernox opened this issue 5 years ago • 9 comments

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.

cibernox avatar Sep 18 '18 16:09 cibernox

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.

brendon avatar Sep 18 '18 22:09 brendon

@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?

oyeanuj avatar Apr 12 '20 14:04 oyeanuj

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

brendon avatar Apr 13 '20 21:04 brendon

@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 :)

oyeanuj avatar Apr 13 '20 21:04 oyeanuj

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

pyrat avatar Mar 25 '21 15:03 pyrat

@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:

  • On Members page, show all groups they belong to and allow them to re-order that list.
  • On Groups page, show all members that belong on it and allow admin to re-order that list.

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?

oyeanuj avatar Aug 31 '22 19:08 oyeanuj

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

brendon avatar Aug 31 '22 21:08 brendon

@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!

oyeanuj avatar Aug 31 '22 22:08 oyeanuj

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

brendon avatar Aug 31 '22 22:08 brendon