ranked-model
ranked-model copied to clipboard
Default value for the position column?
Seems like nil values should be avoided for the position column to avoid problems with ranked_model. (IMHO This should be mentioned in docs!)
Would this be the recommended practice assuming we would want new items to be at the bottom as default?
t.integer :sort_order, :default => RankedModel::MAX_RANK_VALUE
This kind of trouble is one reason I want to use this instead of acts-as-list. I'd hoped there would be a validator or before-save hook handling this, and if not there probably should be?
I wouldn't do it with a constant value in the schema like this, as what order will things come back in when they have the same rank? Does it untangle them using created-at or id? It seems like something to avoid.
This should not be needed. RankedModel runs handle_ranking on each save (see: https://github.com/mixonic/ranked-model/blob/master/lib/ranked-model.rb#L18) and that in turn will call index_from_position (https://github.com/mixonic/ranked-model/blob/master/lib/ranked-model/ranker.rb#L107) which defaults new records to the last position (https://github.com/mixonic/ranked-model/blob/master/lib/ranked-model/ranker.rb#L132). You can also create a record with an explicit position value of :first, :last, or :middle as well as any integer position.
assure_unique_position also runs to catch potential rank conflicts. See https://github.com/mixonic/ranked-model/blob/master/lib/ranked-model/ranker.rb#L139.
I haven't seen the problem @alexhanh mentions here, but I'd welcome more info.
Great, thanks for the explanation & links.
Maybe, it's worth mentioning in README that you shouldn't use default value of 0 for sort_order columns?
I noticed that if I specify default: 0 in migration and try to create a new item, I always end up with sort_order == 0. I can override it with sort_order_position = :last, but it seems like an overkill, because ranked-model correctly adds an item to the end of the list when there's no default value for sort_order.
FWIW, this just bit me (defaulting the column to zero causing some strange ordering issues). Be nice to add a warning to the README.
so what should be the default value?
@guyisra You shouldn't specify any value at all.
FWI, if new record positioned to the top is desired, should hook the self.xxx_position ||= :first in the before_validation block.
Because when RankedModel is included(usually at the top of model), it hooked it's handle_ranking to the before_save callback. So to ensure ||= :first is set before handle_ranking is ran, put the line in before_validation is a way.
I know this is an old issue, however I am trying to find out what to do when I add raking to an already existing resource.
Should I have done an update on all records setting them to RankedModel::MAX_RANK_VALUE ?
Two years later, funny that I found this. I am having the same problem as @donatoaz. Any solution known yet?
It's been a long time, but I believe what I did was to run inside the migration an update setting the values to an incremental value evenly spaced apart by RankedModel::MAX_RANK_VALUE / MyModel.count. Since my tables were not so big, I had no performance issues. But be aware that if you are running against a table with, perhaps, millions of records that you might have issues.
If you decide to go along this path, just remember this: https://blog.makandra.com/2010/03/how-to-use-models-in-your-migrations-without-killing-kittens/
Thanks for the comment. For me, this was my solution:
class AddSortId < ActiveRecord::Migration[5.0]
def up
add_column :items, :sort_order, :integer
table_name = "items"
execute "UPDATE #{table_name} SET sort_order = id;"
end
def down
remove_column :items, :sort_id
end
end
This is similar to other proposed solutions above, where the sort_order matches the id at first. I haven't had any problems with this so far, but I am also working on old code with a bunch of hackey code invovled, so this might not be a one-size-fits-all solution.
Closing. I added a check for this on boot.