1

I have seen How to change a nullable column to not nullable in a Rails migration? for the problem of adding a non-nullable column to an existing database table with existing records. As such, I am thinking of doing this to add position sortability to the model using acts_as_list:

class AddPositionToArticles < ActiveRecord::Migration[6.1]
  def change
    add_column :articles, :position, :integer
    Article.where(position: nil).each do |article|
      article.position = 0
      article.save!
    end
    change_column :articles, :position, :integer, null: false
  end
end

However, that is incorrect, because the position needs to be incremental based on relative positioning to the user record, so user.articles are sorted based on a predefined position.

How can I do this in the migration? Will it happen automatically when I add acts_as_list in the article? And so simply, all I need to do is resave the record in the migration (and not set the position)?

How do I make sure they are put in the same order they started at?

2 Answers 2

2
class AddPositionToArticles < ActiveRecord::Migration[6.1]
  def change
    add_column :articles, :position, :integer
    User.find_each do |user|
      user.articles.order(created_at: :asc).find_each.with_index do |article, index|
        article.update_columns(position: index)
      end
    end
    change_column :articles, :position, :integer, null: false
  end
end
0

Felt like a small change was needed. (I'm not eligible to comment yet hence the post & editing requires at least 6 character change)

class AddPositionToArticles < ActiveRecord::Migration[6.1]
  def change
    add_column :articles, :position, :integer
    User.find_each do |user|
      user.articles.order(created_at: :asc).find_each.with_index do |article, index|
        article.update_columns(position: index + 1)
      end
    end
    change_column :articles, :position, :integer, null: false
  end
end

acts_as_list using 1 index i.e the positioning starts with 1 instead of 0.

Not the answer you're looking for? Browse other questions tagged or ask your own question.