position column is not incremented with Rails v3.0.2 #10

manuelmeurer opened this Issue Nov 21, 2010 · 6 comments

4 participants


I am using this plugin for several months already without problems in a Rails 3 app.
Now I updated from Rails 3.0.1 to 3.0.2 and suddenly the position column is not incremented beyond 2... meaning I have the following:

class Question < ActiveRecord::Base
  has_many   :answers

class Answer < ActiveRecord::Base
  belongs_to :question

  acts_as_list :scope => :question

My Answer model has a position column. When I create X answers for a question, I expect the positions to be 1, 2, 3, and 4.
With Rails 3.0.2 they are 1, 2, 2, and 2.
I tried running the tests included in the plugin locally and all passed, even with AR 3.0.3.
If anyone has a pointer to what might be the problem, I could investigate further.


I just noticed this myself. If I remove default_scope order('position') from the models I'm having trouble with, the problem goes away.


Yes, works for me as well when default_scope is removed.
The culprit is https://github.com/rails/acts_as_list/blob/master/lib/active_record/acts/list.rb#L203.
When the default order is "position", the SQL generated contains "ORDER BY position, position DESC", which obviously orders by position, not "position DESC" as acts_as_list assumes... since default_scope is considered bad anyways, I will just make do without it.


I've just come across this issue too and I am also using default_scope order('position') in my models.

I'm happy to go ahead and remove it, as that seems to do the trick...

Just wondering, why is default_scope "considered bad" and what are the alternatives?

Is a patch that fixes this issue going to be more appropriate?


I just googled a bit and the general opinion seems to be that default_scope creates more problems than it solves. The alternative is to specify the scope explicitly every time.
Fixing acts_as_list is definitely possible.


Ok cool, I'll bear that in mind. Though in this case I think that automatically ordering by an enforced position column makes a lot of sense.

As I am developing a Rails engine gem, that depends on acts_as_list, I can't depend on gems from git repositories (unless bundler lets me and I missed it...) so I've gone with the following monkey patch.

Hopefully it'll help someone!

ActsAsList::InstanceMethods.module_eval do

  def higher_item
    return nil unless in_list?
    acts_as_list_class.where("#{scope_condition} AND #{position_column} < #{send(position_column).to_s}").except(:order).order("#{position_column} DESC").first

  def lower_item
    return nil unless in_list?
    acts_as_list_class.where("#{scope_condition} AND #{position_column} > #{send(position_column).to_s}").except(:order).order("#{position_column} ASC").first

  def bottom_item(except = nil)
    conditions = scope_condition
    conditions = "#{conditions} AND #{self.class.primary_key} != #{except.id}" if except
    acts_as_list_class.where(conditions).except(:order).order("#{position_column} DESC").first


I have created a fork with @andypearson's fix included: https://github.com/haihappen/acts_as_list

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment