0

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

Tiago
  • 673
  • 1
  • 8
  • 24

1 Answers1

2

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
Alex Buschle
  • 166
  • 5