Can anyone show me how to edit the following migration to change :phone integer to string?
class CreateContactInfos < ActiveRecord::Migration
def change
create_table :contact_infos do |t|
t.integer :phone
t.string :facebook
t.references :user
t.timestamps
end
add_index :contact_infos, :user_id
end
end
Thanks in advance!
I guess you already migrated the one you're showing, so create another in which you'd put:
change_column :contact_infos, :phone, :string
I have added some more explanation to this.We need to generate a new migration
rails g migration change_phone_to_be_string_in_contact_infos
If we open up the migration we should see something like this
class ChangePhoneToBeStringInContactInfos < ActiveRecord::Migration[5.0]
def change
end
end
What we call this migration will have no impact on what we need to do next, but future we and other developers will thank us for naming our migration appropriately.
As you can see the change method is sitting empty. We need to manually add some code here.
class ChangePhoneToBeStringInContactInfos < ActiveRecord::Migration[5.0]
def change
change_column :customers, :phone, :string
end
end
After Saving this file just do rake db:migrate we can see changes we want.
For a reversible migration, use:
def up
change_column :contact_infos, :phone, :string
end
def down
change_column :contact_infos, :phone, :integer, using: "phone::integer"
end
Convert column type string into integer in rails migration :
def change
change_column :contact_infos, :phone, :integer, using: 'phone::integer'
end
Convert column type integer into string in rails migration:
def change
change_column :contact_infos, :phone, :string, using: 'phone::string'
end
Related
I have a migration file called [timestamp]_create_posts.rb.
I found that I made the column with a wrong data type. I need to make t.text :content instead of t.string :content.
I include the code from the above file:
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :title
t.string :content
t.timestamps null: false
end
end
end
I kinda know that I should not directly change the file but rollback migration and change the schema and do the migration again. But I wasn't sure whether that's a right way to do it. It would be really nice if someone can guide me through this. I'm not really familiar with Rails.
You should not rollback anything. You should create a new migration, that will change a column with following content:
class UpdatePostsChangeContentColumn < ActiveRecord::Migration
def change
change_column :posts, :content, :text, limit: 60000 # or whatever
end
end
or, even better, to supply the reasonable rollback of this migration:
class UpdatePostsChangeContentColumn < ActiveRecord::Migration
def up
change_column :posts, :content, :text, limit: 60000 # or whatever
end
# back to previous version
def down
change_column :posts, :content, :string
end
end
The other option if you are just in the development is just to Drop you database and recreate it. Then you can modify that file, but THIS IS NOT ADVISED. I have done this again in development where i didn't care about recreating my database
rake db:drop
rake db:create
rake db:migrate
There are two ways to change the column in table:
You can use rake db:rollback VERSION=file_version and then after that you can change datatype manually.
Generate another migration file. e.g rails g migration RemoveColumnToPost and the you can add following codes:
def up
change_column :posts, :content, :text
end
def down
change_column :posts, :content, :string
end
And then use rake db:migrate
I've got a companies table in my database with two columns (size and state) that I wish to add default values to. Currently there is no default value and the columns are not set to null: false. I've tried using the update_column and update_column_default methods as outlined in the docs, but neither seems to be doing anything. I'm able to run the migration but there are no changes to the table.
I've tried update_column like so:
class AddDefaultValuesToCompanies < ActiveRecord::Migration
def change
def up
change_column :companies, :state, :string, default: 'MA'
change_column :companies, :size, :string, default: '1-10'
end
def down
change_column :companies, :state, :string, default: nil
change_column :companies, :size, :string, default: nil
end
end
end
I've also tried using update_column_default like so:
class AddDefaultValuesToCompanies < ActiveRecord::Migration
def change
def up
change_column_default(:companies, :state, 'MA')
change_column_default(:companies, :size, '1-10')
end
def down
change_column_default(:companies, :state, nil)
change_column_default(:companies, :size, nil)
end
end
end
What am I missing here?
Your migration will only change the default value for newly created records. I would write a rake task to update the existing values in the DB. Use something like
Companies.where(state: "").map{|c| c.update_attribute(state: "ma")
I recently added new columns to my database (sqlite) for Media and it shows that the columns are inserted, but the new columns will not update on Medium.new
My original database:
class CreateMedia < ActiveRecord::Migration
def change
create_table :media do |t|
t.string :name
t.string :location
t.timestamps
end
end
end
These columns update on Media.new
class AddMetaToMedia < ActiveRecord::Migration
def change
add_column :media, :ext, :string
add_column :media, :l_mod, :string
add_column :media, :d_create, :string
end
end
and I am calling
Medium.new(name: f, location: str, ext: ex)
ext will not update to ex = File.extname(f), which I know has a value through print statements/console. Am I calling Medium.new wrong? Why is it updating name and location but not the new columns?
edit: Here is my model, I've tried with and without attr_accessible/attr_accesor
class Medium < ActiveRecord::Base
attr_accessor :ext, :d_create, :l_mod
end
Mostly for those who find this later...may also need to whitelist new params in interested controllers
attr_accessor :ext, :d_create, :l_mod remove this line from your model and try again.
Now you have these attributes in DB so Rails will do this job automatically
I have a model with a column of type integer which I want to convert to type string. Now I'm looking for the best way to change the column type without losing the data. Is there a painless way to accomplish this?
A standard migration using the change_column method will convert integers to strings without any data loss. rake db:rollback will also do the reverse migration without error if required.
Here is the test migration I used to confirm this behaviour:
class ChangeAgeToString < ActiveRecord::Migration
def self.up
change_column :users, :age, :string
end
def self.down
change_column :users, :age, :integer
end
end
for postgres
in migration
change_column :table_name, :field,'boolean USING (CASE field WHEN \'your any string as true\' THEN \'t\'::boolean ELSE \'f\'::boolean END)'
and to any valid type similar
for postgresql, change table column datatype integer to string,
rails migration like this with up and down actions
class ChangeAgeToString < ActiveRecord::Migration
def self.up
change_column :users, :age, 'varchar USING CAST(age AS varchar)', null: false
end
def self.down
change_column :users, :age, 'integer USING CAST(age AS integer)', null: false, default: 0
end
end
If it's a one-off you can just change the column type in the database (since no info is lost moving from int to varchar)
For MySQL, this would do it:
ALTER TABLE t1 MODIFY col1 VARCHAR(256)
If you're using SQLite you won't have to do anything.
You can try something like this:
change_column :table_name, :column_name, 'integer USING CAST(column_name AS integer)'
or even better:
change_column :table_name, :column_name, :integer, using: 'column_name::integer'
You can read more about this topic here: https://kolosek.com/rails-change-database-column
If you use Postgres, you can't implicitly cast a string back to an integer, so the way to make the change reversible is:
class ChangeAgeToString < ActiveRecord::Migration
def self.up
change_column :users, :age, :string
end
def self.down
add_column :age_integer
User.connection.execute('UPDATE users SET age_integer = cast(age as int)')
remove_column :users, :age
rename_column :users, :age_integer, :age
end
end
I am trying to run a migration in Rails 3, I wish to add a column to a table, the code looks like this:
class AddConstAdr < ActiveRecord::Migration
def change
change_table: constants do |t|
t.add_column :home_address, :string
end
end
end
When I do rake db:migrate I get an error saying undefined method 'add_column'. I am confused as to why this is happening, can anyone help?
You seem to be mixing two different ways of doing a migration. You probably want this:
def change
change_table :constants do |t|
t.string :home_address
end
end
or this:
def change
add_column :constants, :home_address, :string
end
Both forms should do the same thing: add a home_address string column to the constants table.
I'm also assuming that your change_table: constants is just a typo that should have been change_table :constants.
Further information may be found in the Migrations Guide.
You should do as below:
def change
add_column :constants, :home_address, :string
end