232

I need to change my column type from date to datetime for an app I am making. I don't care about the data as its still being developed.

How can I do this?

Luke Peterson
  • 7,732
  • 8
  • 41
  • 45
jdog
  • 9,310
  • 19
  • 74
  • 146

5 Answers5

513

First in your terminal:

rails g migration change_date_format_in_my_table

Then in your migration file:

For Rails >= 3.2:

class ChangeDateFormatInMyTable < ActiveRecord::Migration
  def up
    change_column :my_table, :my_column, :datetime
  end

  def down
    change_column :my_table, :my_column, :date
  end
end
Polsonby
  • 22,484
  • 19
  • 56
  • 73
apneadiving
  • 110,730
  • 25
  • 209
  • 207
  • 27
    You're right, I just assumed a beginner would choose the latest technology available, but that's, of course, unsure – apneadiving Mar 04 '11 at 08:46
  • 12
    The question is tagged "ruby-on-rails-3" – Sucrenoir Feb 07 '13 at 13:27
  • 2
    @Sucrenoir Yeah the tag was added by apneadiving after he answered. – Jason Feb 26 '13 at 22:52
  • Syntax changed in Rails 4, s. response by Thomas Klemm – geekQ Feb 17 '14 at 08:35
  • 10
    If you're wondering why a single `change` method isn't used instead of the `up` and `down` methods, it's because [the `change` method doesn't support the `change_column` migration definition](http://guides.rubyonrails.org/migrations.html#using-the-change-method). – Dennis Feb 25 '14 at 21:35
  • 2
    This answer is only partially correct, you can not use change_column inside change even on rails 4 or down migration will not work. You should use up/down no matter the version of rails. – Alan Peabody Jul 18 '14 at 18:31
  • @AlanPeabody rails doc on migrations states the contrary, do you have something to back what you're saying? – apneadiving Jul 19 '14 at 07:14
  • 1
    @apneadiving change_column may work in some limited scenarios, but generally it is not really safe to use it in change. See: http://guides.rubyonrails.org/migrations.html#using-the-change-method and try a few different examples and you will see many break. – Alan Peabody Jul 21 '14 at 16:09
79

Also, if you're using Rails 3 or newer you don't have to use the up and down methods. You can just use change:

class ChangeFormatInMyTable < ActiveRecord::Migration
  def change
    change_column :my_table, :my_column, :my_new_type
  end
end
Martin Tournoij
  • 23,567
  • 24
  • 90
  • 127
Lee McAlilly
  • 8,300
  • 10
  • 52
  • 77
  • 79
    The change method only works with reversible migrations. The code above would throw a ActiveRecord::IrreversibleMigration exception. Only methods in http://api.rubyonrails.org/classes/ActiveRecord/Migration/CommandRecorder.html should be used in the change method. – davekaro Jan 09 '13 at 16:24
  • 3
    I am running Rails 4 and did this kind of migration before. CHANGE DOES NOT WORK! @davekaro's comment is correct. – harryt Oct 30 '14 at 03:51
  • 3
    For Rails 5, this is the correct and working solution. – W.M. Sep 22 '16 at 18:34
  • 3
    When being reversed, how would it know what the old column type it should change back to is? – Andrew Grimm Mar 30 '17 at 02:24
  • @AndrewGrimm you are correct. This is what I see when I try to reverse my migration: `This migration uses change_column, which is not automatically reversible.` `To make the migration reversible you can either:` `1. Define #up and #down methods in place of the #change method.` `2. Use the #reversible method to define reversible behavior.` – Marklar Aug 06 '17 at 08:40
42

In Rails 3.2 and Rails 4, Benjamin's popular answer has a slightly different syntax.

First in your terminal:

$ rails g migration change_date_format_in_my_table

Then in your migration file:

class ChangeDateFormatInMyTable < ActiveRecord::Migration
  def up
   change_column :my_table, :my_column, :datetime
  end

  def down
   change_column :my_table, :my_column, :date
  end
end
Community
  • 1
  • 1
Thomas Klemm
  • 10,030
  • 47
  • 54
23

There's a change_column method, just execute it in your migration with datetime as a new type.

change_column(:my_table, :my_column, :my_new_type)
Nikita Rybak
  • 64,889
  • 22
  • 150
  • 172
1

AFAIK, migrations are there to try to reshape data you care about (i.e. production) when making schema changes. So unless that's wrong, and since he did say he does not care about the data, why not just modify the column type in the original migration from date to datetime and re-run the migration? (Hope you've got tests:)).

fakeleft
  • 2,732
  • 1
  • 27
  • 32
  • 2
    You could potentially care about using a migration in a development environment, even if you don't care about the data, if you are working in a team and you want your schema change to propagate to all other developers in your team. – Jose B May 29 '14 at 04:19
  • I'm having trouble seeing what advantage having the additional migration to change a column gives you in this situation. What is wrong with changing the original migration that created the column? In either case, each team member has to rerun all migrations to get the new schema. – fakeleft May 29 '14 at 10:02
  • If you use a new migration, you can just undo the migration that changed the column type. If you were to edit the original, you would have to rollback that edit and rerun the migrations after that. – jazzpi Aug 03 '15 at 16:46
  • This is actually a very prudent answer considering there's no production data yet. For those worrying about other team members, that's what `rake db:migrate:reset` is for. – Ryan McGeary Feb 06 '16 at 00:03