Search code examples
ruby-on-railsrails-migrationsfriendly-id

Creating a Rails Migration to add a Friendly_id column (which is null) to a table with data


I have a table with data and I would like to add friendly_id.

I don't know how to build my migration as I can't create a table with :null=>false when there's data in it. What I would like to do, was for the migration to run the FriendlyId so it builds the slug and inserts it to the database.

My current Migration is as follows:

class AddSlugToSite < ActiveRecord::Migration
  def up
    add_column :site, :slug, :string
    change_column_null :site, :slug, false

    add_index :site, :slug, :unique => true
  end

  def down
    remove_column :site, :slug, :string
  end
end

And my model:

class Site < ActiveRecord::Base
    extend FriendlyId
    friendly_id :name, :use => :slugged
end

This doesn't work as Rails can't create a field with null=>false when there's already data in there.

How can I do it?

Thanks


Solution

  • To solve this, you need to add the column, but do not put the null:false.

    After that, make a rake task or another migration to populate this column, and only after that, you execute other migration to execute change_column_null :site, :slug, false

    Or you could do all of that in one migration, but that could be slow:

    class AddSlugToSite < ActiveRecord::Migration
      def up
        add_column :sites, :slug, :string
    
        Site.where('slug is null').each do |site|
          site.slug = nil # The documentation says this will regenerate the slug
          site.save!
        end
    
        change_column_null :site, :slug, false
    
        add_index :sites, :slug, unique: true
      end
    
      def down
        remove_column :sites, :slug, :string
      end
    end