I have the following model:
class Product < ActiveRecord::Base
end
How can I add a field to it?
What is the type of the field you wish to add? If it is a string do it like below:
rails generate migration add_field_to_products field:string
Where 'field' is the name of the field you want to add, so rename accordingly.
Then do in the command line rake db:migrate and after that the field should be in the model.
Also, this question is a duplicate of: Adding a column to an existing table in a Rails migration . There is more discussion of this there if it's still unclear.
You should generate a separate migration with rails g migration [name], where you declare your column:
add_column :products, :[column_name], :[datatype]
Where [column_name] is the name of the column you want to add and [datatype] stands for it's datatype: string, integer and etc.
After that you should run migration with rake db:migrate to add new column to your table.
Related
How do I create a new field in an existing table using the Ruby command prompt?
I created the model (and migrated it) but I forgot to add a field - how would I go about this?
Generate a new migration to add a new column to table.
rails g migration add_column_name_to_table_name column_name:type
This will create a migration class like below:
#config/migration/20150304121554_add_column_name_to_table_name.rb
class AddColumnNameToTableName < ActiveRecord::Migration
def change
add_column :table_name, :column_name, :type
end
end
Here, column_name, table_name and type should be your desired name and type. Than run rake db:migrate command.
There are two ways to make changes in your situation:
Roll back the last migration
Add the new field in a new migration
Undoing the last migration should only be done if you have not yet pushed the migration to a public server. Here's how to do it:
Run rake db:rollback
Add the new field to the same migration file you originally used
Run rake db:migrate
Option 2:
To add the field in a new migration:
rails g migration AddFieldNameToTableName
For example, if your field is name and your table is users, you would run:
rails g migration AddNameToUsers
This will create a new migration file whose name starts with today's date and ends with add_name_to_users.rb. Open the file and add the field using the add_column command, like this:
class AddNameToUsers < ActiveRecord::Migration
def change
add_column :users, :name, :string
end
end
Save the file, then run rake db:migrate.
I encourage you to read the Rails migrations guide to learn more.
I have a rails 4 app.
I have two tables, one for 'scope' and one for 'data'. Data belongs to scope. I forgot to add a foreign key when I set up data and I'm trying to write a migration to add one now.
I have created a change table, but the migration I've written isn't working.
I can't follow the rails guides example because it isn't consistent with the experience I'm having in my setup (not sure why).
The migration I have is:
class AddFKeyToData < ActiveRecord::Migration
def change
add_foreign_key :data, :scopes
end
end
Please can you help me identify the problem.
Thank you
Rollback this migration by:
rake db:rollback
Then go into your migration and edit add_foreign....
to:
add_column :data, :scope_id, :integer
Should work!
Hello I am about to attempt to run a rails migration on a database of skills that has a :title and :description. I need to remove the description field and I assume it will look something like this:
rails migration remove_column :skills, :description
I am running it by you pros before I attempt it and end up breaking something on accident. Please let me know if I have the right idea about removing the description field from the database. Thanks a lot!
If skills is the name of your table and description is the name of the column you want to remove, you can type rails g migration RemoveDescriptionFromSkills in your terminal. This will generate a migration file with the name [timestamp]_remove_description_from_skills.rb, located in db/migrate. Edit this file so that it contains the following:
class RemoveDescriptionFromSkills < ActiveRecord::Migration
def change
remove_column :skills, :description
end
end
Then type rake db:migrate in your terminal, and the column will be removed.
For more information, check out this helpful Stack Overflow post: https://stackoverflow.com/a/1992045/3723769.
Note: this answer is intended to describe how to perform the migration. As a safety measure, you should do what Michael Durrant advises before migrating: https://stackoverflow.com/a/25006727/3723769.
Here's some of the things that some to mind:-
check the existing values to see if there's any data you want
see if any indexes exist that should also be dropped.
search the application for that field name
see if there's an existing rails migration that you can use to DOWN the change
Finally, I would consider creating a change migration as normal, i.e. one that actaully adds the field and then I would run it using the down syntax to remove the field.
I have already read the documentation of "migrate" on Rails 3 (Rails 3.0 Relese Notes Migrate) but I have some doubts.
e.g. I created two class:
rails generate scaffold User name:string age:integer height:float
rails generate scaffold Hat type:string width:float height:float
This create models, controllers, ... User and Hat and its migrate class: xxx_create_users.rb and xxx_create_hats.rb
Ok, now we guess we want modify User class and we delete height attribute, and we add the relationships between Users and Hats:
User
class User < ActiveRecord::Base
attr_accessible :name, :age
has_many :hats
end
Hat
class Hat < ActiveRecord::Base
attr_accessible :type, :width, height
belongs_to :user
end
Options that I guess:
I remove all files xxx_create_xxx.rb and then I will create again with: rails generate migration CreateUser (and the same for Hat)
I create a new migration file: rails generate migration MyNewMigration where I codify by hand all changes.
Is there another way to automate changes in my classes for passed it to the database? What is the correct way to proceed?
The idea of migrations is that you have a stringent storyline where you can start at any point, forward and backwards. This means that it should not ever be necessary to delete a migration.
Instead, you create a new migration that will change, remove or add database fields.
In your example, you would leave the old migration where it is and then create a new migration like so:
rails g migration change_user_fields
And inside def up you write
remove_column :table_name, :column_name
change_column :table_name, :column_name, :data_type
Add a def down - this will be run whenever the migration is reversed by rake db:rollback. Inside def down put:
add_column :table_name, :column_name # add the field that you removed (s.a.)
change_column :table_name, :column_name, :data_type # change back to old data type
Rails 3 gives you a nice shortcut for adding and removing fields from a table by doing:
rails g migration add_something_to_users name:string
which will automatically create a migration that adds a field called name with a data type of string to the users table. Or
rails g migration remove_something_from_users name
which will automatically create a migration to remove the name field from the users table. These shortcuts and the created migration files do not need a def down - rails will automatically be smart enough to figure that out when reversed.
In both cases, you can replace the word "something" with whatever you like.
However, I know of no way to use a shortcut to change data types, so you need to go in the migration file and do that manually.
Eventually, just run rake db:migrate and you'll be all set!
Scaffold only automate a fixed command, so if you create a model and its attributes with scaffold, your migration will only contain the fields you specify on the command line. There is no way to keep track of changes automatically.
If you add/remove/change something on your database, you have to manually set it. Migrations are useful because you can keep track of these changes on time.
So i recommend you to never delete a migration. In this particular case you described, you just have to create another one to reflect the new change on your database, keeping a total of 3 migrations, instead of deleting and creating another.
The answer to your question should be alternative 2. But you don't have to do it all by hand if you just want to add or remove attributes:
http://guides.rubyonrails.org/migrations.html#creating-a-standalone-migration
I am trying to add one column in one table using migration up. I have created migration for that and ran rake db:migrate:up[version] it added the column in my table but I don't see that attribute in my respective model. Am I missing something here to do? Below is my snippet ...
migration 6, :add_role_users do
up do
execute <<-SQL
ALTER TABLE users
ADD COLUMN role varchar(32) DEFAULT NULL
SQL
end
down do
execute <<-SQL
ALTER TABLE users
DROP COLUMN role
SQL
end
end
After running the above migration I don't see below line in my User model
property :role, , String, :length => 32
Please suggest, I am using Rails 3.0 so I can't use migration Change method.
Rails automatically detects and assigns model attributes based on your table's columns. For some generic information about how this is done, this guide is invaluable: http://guides.rubyonrails.org/migrations.html
Anyway, here's how I would run a migration that adds a role column to the users table.
In your console, run rails g migration add_role_column_to_users role:string. (Since the migration name ends with "users", Rails will automatically know to apply this migration to the users table. Specifying role:string is just a command line shortcut that automatically adds t.add_column :role, :string to your migration. After running this command you should be able to find your new migration in the db/migrate/ directory of your app.)
In your console, run rake db:migrate to migrate the database to your new schema.
That's it! You should now have a "role" column on your "users" table. You can verify this by entering your Rails console with rails c, and bringing up your user model's column names with User.column_names. You should see "role" there.