ranked-model icon indicating copy to clipboard operation
ranked-model copied to clipboard

Default value for the position column?

Open alexhanh opened this issue 12 years ago • 12 comments
trafficstars

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

alexhanh avatar Dec 06 '12 15:12 alexhanh

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.

nruth avatar Feb 03 '13 18:02 nruth

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.

mixonic avatar Feb 03 '13 19:02 mixonic

Great, thanks for the explanation & links.

nruth avatar Feb 03 '13 22:02 nruth

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.

scarfacedeb avatar Apr 15 '14 08:04 scarfacedeb

FWIW, this just bit me (defaulting the column to zero causing some strange ordering issues). Be nice to add a warning to the README.

Undistraction avatar Jul 10 '14 15:07 Undistraction

so what should be the default value?

guyisra avatar Sep 09 '14 07:09 guyisra

@guyisra You shouldn't specify any value at all.

scarfacedeb avatar Sep 26 '14 06:09 scarfacedeb

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.

snow avatar Nov 02 '14 13:11 snow

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 ?

donatoaz avatar Mar 01 '16 16:03 donatoaz

Two years later, funny that I found this. I am having the same problem as @donatoaz. Any solution known yet?

dylantyped avatar Jul 11 '18 18:07 dylantyped

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/

donatoaz avatar Jul 12 '18 12:07 donatoaz

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.

dylantyped avatar Jul 12 '18 15:07 dylantyped

Closing. I added a check for this on boot.

brendon avatar Jun 04 '24 04:06 brendon