Database changes not reflecting after Rake and Migrate commands - ruby-on-rails

I am working very first time on Rails Application. I am using Rails 4. As per tutorials and books I used Rails migrate command to generate initial schema. After that I called rake db:migrate. The message says table created but when I go to db/development.sqlite3 I find no table at all.
Following is the code of Migration File
class CreateEvents < ActiveRecord::Migration
def change
create_table :events do |t|
t.string :title
t.text :summary
t.integer :total_impacts #added later but does not reflect in db
t.integer :current_status #added later but does not reflect in db
t.timestamps
end
end
end
What steps am I missing?

Since I am on early stages of Database I rather called db:schema:load after making changes in schema.rb file.
I guess add_column should work too but not sure.

After reading the comments, I assume that the table was successfully created but that it's only a problem with the :total_impacts and :current_status columns.
If you run a migration once, the database knows that it's already been through it and won't run it again unless specified explicitly (rake db:migrate VERSION=...).
So if you write a migration, run it, then update it and try to run it again, the stuff you've just added (like a new column) won't appear in your database (because the migration has already been run in the database point of view).
If you realize after running the migration that you forgot some things, you have two options:
You can write another migration for the things you want to add/delete and run it. (Easy stuff).
You can rollback the migration (play the down part), edit it and run it again (play the up part). This one can be a bit more tricky depending on when you realize your mistake (has some data related to that migration already been added? etc).

Related

Running rails migration moves indexes around in schema

The app in question was originally created as a Rails 4 app, and later upgraded to Rails 5.
I will create a rails migration that might look like this:
class AddPubliclyVisibleToGcodeMacros < ActiveRecord::Migration[5.0]
def change
add_column :gcode_macros, :publicly_visible, :boolean, default: false
end
end
And when I run it, I expect the schema to have a few lines updated, specifically adding t.boolean "publicly_visible", default: false
to the gcode_macros table.
However, running the migration creates a LOT of changes to my schema, mostly just moving indexes from outside a create_table block, into it.
Im quite confused over whats going on here. This isn't something that happened all of a sudden, I've just been working around it for a while now.
Any help would be greatly appreciated!
The answer is that this is just how the schema dumper works in Rails. It takes the schema from the database, absolutely irrelevant from how you created the structure in the first place, whether with migrations or direct sql statements.
So when you create a new migration or change anything in the db a new schema is dumped based on the database.
Edit
I should add that schema.rb is not updated if the db is changed directly with sql statements, that is not through a migration. Only when either
rake db:migrate
or ...
rake db:schema:dump
are run is the schema.rb file updated.

Why isn't my schema.rb file updated?

I recently looked at my schema.rb file and was alarmed to find that certain columns that do exist in my database do not appear, and some tables are missing entirely. The missing columns were added to the database through "def change add_column" migrations, though some columns that were added in that way do appear as expected in schema.rb.
On closer inspection, I realized that schema.rb has not been updated since I created the Users table.
20151019205241_create_users.rb:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps null: false
end
end
end
This has not caused an issue for me in practice, but I thought schema.rb was supposed to be kept automatically updated, and that it would be important to have it updated in order to recreate the database. Can anyone help me figure out why it would not be updating?
One possibility is that it stopped being updated when I switched my database from sqlite3 to postgresql. I don't remember exactly, but I think the timing makes sense.
You can use rake db:schema:dump to re-create the file from the current database structure.
Schema file is independent from the driver so migrating from sqlite3 to PostgreSQL shouldn't matter. Make sure that version for definition in the file is not greater than current the current date. You can also add the whole file to the question's snippet.

Why can I no longer rake db:migrate when adding new columns to my table? Can I add columns manually in the migration file or should I generate one?

Good morning everyone,
I am trying to complete the calender app from Codeacademy, and I need to complete the following steps.
Open the migration file in db/migrate/ for the days table, and add the following columns:
a datetime column called date
Open the migration file in db/migrate/ for the days table, and add the following columns:
a datetime column called date
Open the migration file in db/migrate/ for events tracks table, and add the following columns:
a string column called name
a datetime column called from
a datetime column called to
a string column called location
a references column to the Day model
So far, I have added it manually to the migration files like so:
class CreateDays < ActiveRecord::Migration
def change
create_table :days do |t|
t.datetime :date
t.timestamps
end
end
end
class CreateEvents < ActiveRecord::Migration
def change
create_table :events do |t|
t.string :name
t.datetime :from
t.datetime :to
t.string :location
t.timestamps
#Not sure how to add references column????
end
end
end
However, I am running into an error when I run rake db:migrate, I get no output. Is there supposed to be an output? I have run rake db:migrate --trace and here is the output:
A migration file is like a script which changes your database in some way. It does not store the state of your database.
It will not do anything unless you run it: your database has a special table to keep track of which ones have been run already, called schema_migrations. When you do rake db:migrate you run all scripts in that folder which haven't been run already, according to that table.
So, if you run a script, then change it, then do db:migrate, it won't run it again because it thinks it's been run already. If it did run it again, it would likely blow up because it would be trying to add lots of columns that already exist.
If you define a table in a migration, then later want to add more columns, you can either roll the migration back (which will drop the table), then run it again with the added columns, or write a new migration which just adds the required new columns. The latter approach is usually best.
Whenever you run rake db:migrate,it runs all the pending migrations using the timestamp which every migration file has ..such as YYYYMMDDHHMMSS_create_products.rb.
Any file which has a migrations greater than the previously run migration timestamp will be picked up during rake db:migrate and then checked whether the changes are present in the db.
For example :
For a migration file 20080906120001_add_details_to_products.rb...if you have ran it then all the changes will be added in the db.if you edit it and then run it again then it won't be picked up as timestamp of migration should be grater then previously ran file,which is not.
You can manually change the migrations by editing few numbers so that it gets picked up again without creating a new file.
I would recommend create a new one as they are way to maintain and are each migration should be unique.
I assume that you have ran the migrations before. So there is a table named schema_migrations where it stores the migration which has already ran so you cannot re run them. The best way to add new columns to an existing table is to create a new migration like this:
rails g migration add_some_columns_to_events name:string
and name the other columns. And still if you need to do it using the existing migration then what you can do is:
rake db:migrate:down VERSION=<version_of_migration>
and then add up the columns in migration file and run:
rake db:migrate:up VERSION=<version_of_migration>
You can also rollback your last migration and re run the migration using:
rake db:rollback
Hope this helps.
You can only run a migration once - if you've already run the migration, you have two options:
You can roll back the migration with rake db:rollback, edit it, and then run it again with rake db:migrate, or
You can generate a new migration and put your changes in it. Then you can run the new migration with rake db:migrate.

Rails Migrations Basic Workflow

Let's say I have a migration that creates a table 'pages' , this is my migration:
class CreatePages < ActiveRecord::Migration
def up
create_table :pages do |t|
t.string "name" , :limit => 50
t.integer "permalink"
t.integer "position"
t.timestamps
end
end
def down
drop_table :pages
end
end
and that I've created the appropriate migration file X_create_pages.rb and ran it(the table is created in the database).
Now after a few days I realize the structure isn't complete and I need to add another column to my pages table .
What is the best practice , do I create a new migration file with add_column method or do I just change the current migration file's up method -e.g just add my columns to the up method (and then move down a version and then up again - so to run the up method?)
The practice should be you create a new migration to add the new column. This becomes the simplest and risk free path. Of course, we can talk about unseen circumstances!
Updating original migration files should not be used after application is released to production; at least this is what the practice should be. But, this also depends on applications, if you don't have a table that is referenced elsewhere then backing up the data, adding the column and restoring the data is also a possibility which is enabled by this approach of directly modifying the original migration file and rolling down that version and migrating up that version again.
While you are on development, the choice I guess is yours. You could choose either!
Once a migration has been checked into source control it shouldn't be changed.
Modifying a migration on your development environment providing it hasn't been checked into source control is perfectly fine.
Once a migration has been checked in it may have been run by your team mates on their development environment or even been deployed and run in production.
Changing previously committed migrations is going to make you very unpopular in your team very quickly as team mates struggle to understand why their database schema is different from yours but all the migrations have been run.

How do I add a new attribute to a migration in Rails 3?

Here's my story: I had something like this set up a while ago.
create_table(:users) do |t|
t.database_authenticatable :null => false
t.recoverable
t.rememberable
t.trackable
t.integer :total_pageviews
and "total_pageviews" worked fine. I could set it to zero, increment it, multiply it, call it, whatever. but let's say i want to add:
t.integer :total_votes
What do I have to do to configure total_votes as an attribute? Whenever I try to use "total_votes", I get undefined method error. I'm thinking that the answer is something like rake db:migrate or similar.
You should not ever alter existing migrations. If you have checked them in to your version control system and somebody else runs them and then you add a new field to them and commit that change, they will not know to get that change. Then you must tell them and it's a pain in the butt to fix.
If you've not committed it yet then rollback the migration (rake db:rollback), make the necessary modification and re-run it again (rake db:migrate).
But in the Real World, you would create a new migration which adds this field using rails g migration add_total_votes_to_users total_votes:integer.
Rails will interpret this migration name and know what to do with it, generating a migration that contains this line:
add_column :users, :total_votes, :integer
Then when you run this migration it will add this total_votes field to the users table which will make an attribute of the same name for all User objects.
Are you adding this after the migration has been run? So, the users table exists and you want to add a column to it? If so, you need go create a migration like
rails generate migration add_total_votes_to_users
Open it up (just to verify that the table and column are correct). Then run the migration.
If you app is in production, then you should create a new migration. If you app is in pre-production stage, and you have a small development team with good communication, then I recommend you to go ahead and modify the migration and then do
rake db:drop
rake db:create
rake db:migrate
then you can commit the modified migration file and let the rest of you team know that that you have changed a migration file.

Resources