removing migration and adding another one with similar stats - ruby-on-rails

I have migration called "sign_substrate" which looks like:
class CreateJoinTableSignSubstrate < ActiveRecord::Migration
def change
create_join_table :signs, :substrates do |t|
# t.index [:sign_id, :substrate_id]
# t.index [:substrate_id, :sign_id]
end
end
end
I would like to remove it, and add similar one instead of her (the one listed below):
class CreateJoinTableCategorySubstrate < ActiveRecord::Migration
def change
create_join_table :categories, :substrates do |t|
# t.index [:category_id, :substrate_id]
# t.index [:substrate_id, :category_id]
end
end
end
What I did was, used command rails d migration CreateJoinTableSignSubstrate which did nothing I think(or it did), because when I restarted my SQLite Manager, the table was still there, so I used and removed I manually from file system (right click delete on migration in files ).
After creating this migrations, what I did was, I went to models, and modified a few models, manually (I am not sure can I do that) and added a couple of new associations in models. (like has_many etc etc)
Ran rake db:migrate after everything.
My questions here are:
What are the correct ways of deleting one migration, and also deleting it from database.
Is my way of adding new associations to models a good one, or I did some mistake.

You can generate the migration to remove a column or delete a table in same way as you do to generate them. From docs:
rails generate migration RemovePartNumberFromProducts part_number:string
generates
class RemovePartNumberFromProducts < ActiveRecord::Migration
def change
remove_column :products, :part_number, :string
end
end
To destroy a model:
rails destroy model ModelName
For your associations doubt, you specify the associations in your models, but the associations are possible only by referencing foreign ids or join tables etc. For them, you will have to generate the suitable migrations anyway; so associations are the team work of migrations + models. Just specifying the associations in models won't actually associate them unless their referencing keys are present.

The step you missed is first rolling back the migration. You should use rake db:rollback to undo the last migration before you remove it and add the new one.

Related

Rails Migration Add_Index issue

I'm trying to add indexing to my users table for the email column. Typing rails g migration add_index_to_users_email generates the migration but the function is empty. The snake casing should be correct, so I'm at a loss as to why the migration is being created but the change function inside is empty.
I've also tried AddIndexToUsersName and the same issue arises.
Any direction on what the issue could be would be greatly appreciated. Only thing I can think of is that I'm using Postgres and not MySQL or SQLite, but that wouldn't matter would it?
As far as I know, migration generators only support addition and removal of columns, with a specified modifier. For example, if you wished to add a new string column phone to the users table, you could use the command
rails generate migration AddPhoneToUsers phone:string
Check the Rails Guides for column modifiers. You can try
rails generate migration AddIndexToUsers email:index
to add an index to the existing column. However, I am not sure if generators support column modification. You can write the migration yourself, assuming the email column already exists on the users table:
class AddIndexToUsers < ActiveRecord::Migration
def change
add_index :users, :email
end
end
Have a look at:
http://guides.rubyonrails.org/active_record_migrations.html
The correct command is
rails g migration AddIndexToUsers email:string:index
This will generate:
class AddIndexToUsers < ActiveRecord::Migration
def change
add_column :users, :email, :string
add_index :users, :email
end
end
Edit the migration file and delete the add_column line, then run the migration.

How to destroy columns mistakenly created by Paperclip in Ruby on Rails

As the title suggests, I accidentally add some random attachment columns to my model. Say I did rails generate paperclip portfolio href
How do I remove those columns created? rails destroy paperclip portfolio href doesnt seem to work!
For recent version rails 4++ Just create a migration Example:
rails g migration remove_attachment_photo_to_course
Then open the migration file
class RemoveAttachmentPhotoToCourse < ActiveRecord::Migration
def change
remove_attachment :courses, :photo
end
end
Then run, to update the table
rake db:migrate
Where:
photo is the name of paperclip attachment you want to remove
courses is the name of table name
I have created a migration file and change the content to:
class RemoveAttachmentHrefToPortfolios < ActiveRecord::Migration
def self.up
remove_attachment :portfolios, :href
end
def self.down
remove_attachment :portfolios, :href
end
end
The problem is it is not the elegant and correct way to do it. I hope someone can improve this answer..
Normally for a migration you run rake db:rollback. Since this was a generator, you can just manually edit the table and drop the columns.
alter table portfolio drop column href_content_type;
alter table portfolio drop column href_file_name;
-- ... etc for each of the Paperclip columns.
You could also create a migration to drop the columns, but that would be overkill unless your whole team also ran the generator or you checked in schema.rb and others ran it also.
Here is an example migration for removing columns:
class RemoveMagazineFromBooks < ActiveRecord::Migration
def change
# This is not used ANYWHERE...
if column_exists? :refinery_books, :magazine
remove_column :refinery_books, :magazine
remove_index :refinery_books, :magazine if index_exists? :refinery_books, :magazine
end
end
end
Notice the test to check if the column is there. Some people may not have run the previous migration and will not have the column.
This comes from the Paperclip documentation:
remove_attachment :portfolios, :href
This will rollback the latest changes to the DB schema:
rake db:rollback
After that, simply delete the migration file.
This is presuming that you didn't commit any of the changes/migrations to a shared repository.
$ rails generate migration RemoveColumnsFromModel portfolio href
should make you a migration that will remove two columns "href" and "portfolio" from some model's table. The migration will look something like:
class RemoveColumnsFromUser < ActiveRecord::Migration
def change
remove_column :users, :foo, :string
remove_column :users, :bar, :string
end
end

How to update database schema without losing original data

Hi guys I would like to know if there's a way not to lose the data if you're trying to rollback your migration just to update the schema ? For example after running rake db:migrate, and after few rounds of data inserted, you want to add in a new attribute to the schema.
So my question is how can i add the new attribute without losing my previous record ? is it possible to do so ? Because all this while i just did by running rake db:rollback STEP= ... and lost all the data i've generated. Just wondering.
Thanks for helping
From:
BC2
if you have an existing table and want to add new attribute in existing table then simple write stand alone migration.
for ex: you have a students table with attribute name, roll_no ... and now u want to add 'address' attribute in students table
$ rails generate migration AddAddressToStudents address:string
will generate
class AddAddressToStudents < ActiveRecord::Migration
def change
add_column :students, :address, :string
end
end
then simply run "rake db:migrate"
You don't need to rollback to update the schema. Just write a new migration to update the existing table.
For example, to add a field to your user table without destroying anything, write a migration like:
class AddFieldsToUser < ActiveRecord::Migration
def change
change_table :users do |t|
t.date :birthday # add new field
t.remove :first # remove a field
t.rename :gender, :sex # rename a field
end
end
end
See here for more info: http://guides.rubyonrails.org/migrations.html#changing-tables

Adding an index to a table I already created in SQLite?

Hi I created a table for a wiki application that I was doing. It was pretty simple in the beginning I had a Questions table and an Answers table. I now want to add users to it. So for that I created a users table and the whole signup thing is ready. The wiki part is working and the users part is working but I am having trouble to merge them together.
I first created a Questions as a scaffold as follows:
rails g scaffold Question title:string body:string
Then Answers as follows:
rails g scaffold Answer question_id:integer content:string
I then tried to add the users_id column after creating the Users table:
rails generate migration add_users_id_to_questions user_id:integer
I then tried to index the user_id column by adding the following line in the migration file:
class AddUserIdToQuestions < ActiveRecord::Migration
def change
add_column :questions, :user_id, :integer
end
add_index :questions, :user_id
end
I do rake:db migrate but it doesnt show the change after I run migration. Is there any other way I can index user_id other than by adding a column to the migration file. I even ran rake db:rollback so the addition of user_id column is gone but when I make the change and run rake db:migrate it gives me an error user_id doesnt exist. It would be greatly appreciated if you could help me how to create the index. I running Rails 3, SQLite as my DB.
Thank you.
Rollback and then re-run the migration with add_index inside the change block.
class AddUserIdToQuestions < ActiveRecord::Migration
def change
add_column :questions, :user_id, :integer
add_index :questions, :user_id
end
end

Rails 3 adding fields to a table

ok i am a noob and i want to know how to add fields to a migration in rails 3, additionally i am using Typus and would like to know if i need to add these fields manually or can i just regenerate the typus and it will just pick the new fields up?
Thanks in advance
Robbie
Migrations are used to add fields to the database, not tell Rails about fields.
Rails will actually inspect the table for its fields, so if you have an existing table, you can create a model called spy.rb and it will know about all fields in spies
To use migrations, run rails generate migration AddScreenshotColumns. Then that file can become:
class AddScreenshotColumnsToTemplate < ActiveRecord::Migration
def self.up
add_column :templates, :screenshot_file_name, :string
end
def self.down
remove_column :templates, :screenshot_file_name
end
end

Resources