How the migration updates a model in Rails3.0 - ruby-on-rails

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.

Related

The Active Record will auto generate name

I study a e-book of Ruby on Rails:
If I create a Active Record below:
class Product < ApplicationRecord
end
Rails Will execute the below code to generate a table:
CREATE TABLE products (
id int(11) NOT NULL auto_increment,
name varchar(255),
PRIMARY KEY (id)
);
There I have a question, I can understand auto generate the major key, but why how to understand the:
name varchar(255),
If the name field is auto generated? and if yes, why it is necessary?
Yes, it will be auto generate. But it's not a activerecord action, it's related to the database. For mysql, if you doesn't set default value for the column, then it will default be NULL, nil in ruby.
Even you didn't set value for specific column, it also need to be display in the database, or visit as product.name, so do necessary.
No,the sql statement to create the table 'products' is not from your model file(product.rb), but from migrate files.
Where you run a Rails rake command: rake g model product name:sring,
it will not only create a model file(product.rb) for you, but also a migrate file in "db/migrate/" folder, naming like "xxxxxx_create_products.rb". Open this file and you will see lines like:
def change
create_table :products do |t|
t.string :name
end
end
That's how Rails knows what columns you want to have in your "products" talbe, and what type they should be.
And this table will not be created, until you run this command: rake db:migrate.

Fixing migration error

I tried to create a migration to add roles to my user tables but i accidentally typed AddRolesToUsers instead of AddRoleToUser. So i tried creating a new migration with the correct AddRoleToUsers but when i tried to run rake db:migrate i got an error :
SQLite3::SQLException: duplicate column name: role: ALTER TABLE "users" ADD "role" integer/Users/miguel/.rvm/gems/ruby-2.2.1/gems/sqlite3-1.3.11/lib/sqlite3/database.rb:91:in `initialize'
I tried rake db:migrate:down VERSION= do delete the one I had to type on but i keep getting the same error . PS: i deleted the migration file manually after running rake db:migrate:down VERSION=
rails g migration AddRoleToUsers role:integer
migration file :
class AddRoleToUsers < ActiveRecord::Migration
def change
add_column :users, :role, :integer
end
end
When you ran the first migration, the role column was added to the Users table. The error on the second migration tells you that much.
To clear the migration pending error, you need to comment out the add_column statement in the new migration.
i.e,
class AddRoleToUsers < ActiveRecord::Migration
def change
# add_column :users, :role, :integer
end
end
Then run the migration. This way, the new migration should run successfully.
You can now uncomment it and delete the previous migration, so that when you deploy, only the newer migration is run and the role column is added successfully.
In that case right click and delete both migration files and start again. The error exists because it thinks you want to add two columns both named role to your users table
UPDATE
In that case, if role already exists in your users table, a migration must've been successfully run and there is no need to run another. As long as the role column is there, trying to add another column called role will always give you an error. If you wanted to test that you are still able to add new columns you can always check by creating a test migration AddSomethingToUsers something:string and rake db:migrate to test, then rake db:rollback to undo..but it all seems like it's worked so I probably my wouldn't mess with it too much.

Creating an empty table, with fixed columns - Ruby on Rails

I'm very new to ruby on rails, been trying to play around with it in the past few days.
Basically trying to: Create a empty table, with fixed columns - Ruby on Rails
I've created a model like so:
rails g model table
rails g migration table
my tables.rb files looks like this:
class Tables < ActiveRecord::Migration
def change
add_column :table, :firstname, :string
add_column :table, :lastname, :string
end
end
(hopefully I created the columns okay)
I then run:
rake db:migrate RAILS_ENV=development
but seem to get an error no such table: table (but I thought I created it ? )
Also what is a good view I can use to see my table on localhost:3000, in a html.erb file?
What you are displaying as your tables.rb file is a migration file, not a model. Models are stored in app/models. Migrations are in db/migrate and have a name that is a datetime stamp followed by the migration name.
Your migration is performing add_column. You can't add_column until you create_table. That migration should have been built using "rails g model table". Please show all migrations with the entire filename.
Check the document that dax provided. The rails generate command uses a stylized command line. Many standard migration functions, such as creating tables and adding columns, can be automatically generated by using the correct migration name. For example:
rails g migration add_url_to_feed url:string
This will create a migration that adds a string column called url to the feed table.
Generally, migrations should do what you need. However there is another command, rake, that you will need. The reference is here. For example:
rake db:create # Create the database from config/database.yml for the current Rails.env
can create the database for you.

Alter Schema in Rails 2

I need to add some columns to a table in my schema. Can someone tell me the best way to do this?
The following seems incomplete or wrong since the schema.rb file did not update to include the new column and all of the corresponding view files (edit,index,new,show) did not update to include the new column. Not to mention the bloat of all of those migration classes that get generated. Thanks
ruby script/generate migration RecordLabelToAlbums record_label:string
exists db/migrate
create db/migrate/20121130125859_record_label_to_albums.rb
Creates this:
class RecordLabelToAlbums < ActiveRecord::Migration
def self.up
end
def self.down
end
end
I then added this:
class RecordLabelToAlbums < ActiveRecord::Migration
def self.up
add_column :albums, :record_label, :text
end
def self.down
remove_column :albums, :record_label
end
end
The I ran:
rake db:migrate
Got This:
Mysql::Error: Table 'albums' already exists: CREATE TABLE albums (id int(11) DEFAULT NULL auto_increment PRIMARY KEY, created_at datetime, updated_at datetime)
The code you added is correct.
The error suggests that for some reason your system appears to think it has not yet run the original migration that created the albums table. The state of migrations (in Rails 2) is specified in a table in the database called schema_migrations -- if this gets confused then it will try to re-run migrations. I am not sure what might cause it to get confused, but I do recall this happened a couple times back in 2008 when I was using Rails 2.x.
The table is simple -- you can see what's in it from a SQL prompt -- just the names of migrations it thinks it has run, I think.
If you don't mind losing some data, you can try rake db:rollback or even rake db:reset to get back to the beginning. rake db:rollback STEP=2 will rollback the last 2 migrations.
If you need the data, correct the contents of the table by adding one or more new records referencing the migrations in app/db/migrations that may have been missed. The order is important, I think (the format changed a little in Rails 3, I don't recall how).
Any time you want to add or change the database schema, use rails to generate a migration, and then run rake db:migrate once it's ready to go.
And just asking: is there any way you can move to Rails 3. It's been out for years now, and Rails 4 is coming soon. You'll find yourself in a backwater of incompatibilities, deprecations, security and performance issues and so on if you don't take the hit and upgrade.

changes to model in ruby on rails

All,
I need clarification on how model changes need to tracked in ruby on rails. I started off by creating a model with say two fields, name and email. Here is what i have done
Created a model by running
"rails generate model user first_name:string last_name:string"
This created a model file
I then added some validations to the files created in user
Used the annotation gem to annotate the class
used "bundle exec rake db:migrate" to move my model to database which created the tables
I now want to add a couple more fields to the model. What steps do i need to follow?
Do i add columns to the database and run some command so that the model(class) is in sync with the db?
Do i delete and recreate the whole model with the new fields?
what is the recommended approach
Venu
You want to use a migration to update the existing table, you can do the entire process from the command line
Assuming you've done
rails generate model user first_name:string last_name:string
previously you would add fields like so;
rails generate migration AddFieldsToModel new_field:string another_field:string....
Rails does magic on the 'AddFieldsToModel' and works out the table name from the value for you.
Once you've created the migration you can look at it in db/migrations and then if you're happy with it just run
rake db:migrate
this will update your database to add the new fields to it. You don't need to do anything to the actual model.rb file - but you will need to re run the annotate task to have it reannotated to the model.rb file.
I am not sure what version of rails your are using .. but int rails 3.x it can be done as
rails generate migration add_fields_user
this creates a file in db/migrate/[timestamp]/add_fields_user.rb
now you can write in the file and run rake db:migrate
add_column :users , :city, :string
What you want to do is run a migration by typing. rails generate migration description_of_migration. This will create an empty migration which you can define what you want to add to your model. In your case it may be something like this:
class DescriptionOfMigration < ActiveRecord::Migration
self.up
add_column :users, :email, :string
end
self.down
remove_column :users, :email
end
end
This makes it so you can migrate both ways on the model.

Resources