I am trying to add a index to a column which already exists in my table by.
I want to add a index on item_id on product_images table
bundle exec rails generate migration AddIndexToProductImages item_id:integer:index
but the code i see in the migration file is
class AddIndexToProductImages < ActiveRecord::Migration
def change
add_column :product_images, :item_id, :integer
end
end
Not sure what could be causing this, can anyone help? Thanks.
Rails will not autogenerate the migration with content just for index
Edit the generated migration with following:
class AddIndexToProductImages < ActiveRecord::Migration
def change
add_index :product_images, :item_id
end
end
Following is the command to generate index migration File:
bundle exec rails generate migration AddIndexesToProductImages item_id:integer:index
In case it does not have proper command to add index, you can edit the generated file with the appropriate index you want to add. You will have to wring following in the change function.
def change
add_index :product_images, :item_id
end
Related
What is the command for removing an existing column from a table using migration?
The column I want to remove is: country:string
From the table: sample_apps
To remove a column with migration:
rails g migration Remove..From.. col1:type col2:type col3:type
In your case:
rails g migration RemoveCountryFromSampleApps country:string
This will generate the following migration in Rails 5.0:
class RemoveCountryFromSampleApps < ActiveRecord::Migration[5.0]
def change
remove_column :sample_apps, :country, :string
end
end
Create migration file:
$ rails generate migration RemoveCountryFromSampleApps country:string
In generated migration file:
class RemoveCountryFromSampleApps < ActiveRecord::Migration
def change
remove_column :sample_apps, :country, :string
end
end
Then run:
rake db:migrate
To remove a column(country here) from table(sample_case)
rails generate migration RemoveCountryfromSampleCase country:string
Above command should generate a file YYYYMMDDHHMMSS_remove_countryfrom_sample_case.rb. under db/migrate folder
class RemoveCountryFromSampleCase < ActiveRecord::Migration[5.0]
def change
remove_column :sample_case, :country, :string
end
end
In my case (I was doing it for more than two columns) only this appears
class RemoveCountryFromSampleCase < ActiveRecord::Migration[5.0]
def change
end
end
remove_column line was not there so I added it manually and then fired the command
rails db:migrate
and it worked for me.
References https://stackoverflow.com/a/2963582
&
Ruby guide on Active Record migration
https://edgeguides.rubyonrails.org/active_record_migrations.html
If want to remove the index too, you do with migration too:
rails g migration remove_post_id_from_comments post_id:integer:index
migration file:
class RemovePostIdFromComments < ActiveRecord::Migration
def change
remove_index :comments, :post_id
remove_column :comments, :post_id, :integer
end
end
then run: rake db:migrate
Do you need to specify the type?
Why not just remove_column :sample_apps, :country or remove_column :comments, :post_id for the samples here? Seems to work and removes a chance for error (text or string).
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
HI I created a Ruby on rails migration file as follows and in the first stage I created tables
then I want to add columns and remove some columns and I modified it as follows
class CreateMt940Batches < ActiveRecord::Migration
def change
create_table :mt940_batches do |t|
t.string :account_number
t.string :transaction_reference_number
t.string :information_to_account_owner
t.string :file_name
t.binary :raw_data_transaction
t.string :sha1_checksum
t.timestamps
end
def self.down
remove_column :account_number, :transaction_reference_number, :information_to_account_owner
end
def self.up
add_column :mt940_batches, :created_by, :updated_by, :integer
end
end
end
but when I ran rake db:migrate nothing has happens. How to accomplish this task . I want to change the model already created as well from this migration file. Um looking a way to do this. Thank you in advance
You should add your remove / add column in a separate migration file.
class FooMigration < ActiveRecord::Migration
def down
remove_column :account_number, :transaction_reference_number, :information_to_account_owner
end
def up
add_column :mt940_batches, :created_by, :updated_by, :integer
end
end
Please note that your up and down method should be idem potent. You should be able to go from one to the other when calling rake db:migrate:down and rake db:migrate:up. This is not the case here.
However here, it seems that you want to achieve 2 different things in a single migration. If you want to add AND remove columns, consider moving each one in a different migration file:
Please read here for more details
You would end up with 2 migrations file like this:
class RemoveFieldsFromMt940Batches < ActiveRecord::Migration
def change
remove_column :mt940_batches, :account_number, :transaction_reference_number, :information_to_account_owner
end
end
class AddFieldsToMt940Batches < ActiveRecord::Migration
def change
add_column :mt940_batches, :created_by, :updated_by, :integer
end
end
Do not edit it if this migration already executed in production env create new one instead
if not you can use rake db:rollback, rollback migrations
Because this migration is already executed. you have to generate a new migration for adding and removing column in your table, i.e. you want to remove file_name from your table :
run this:
rails g migration RemoveFileNameFromCreateMt940Batches file_name:string
re-generate that column:
rails g migration AddFileNameToCreateMt940Batches file_name:string
Than run rake db:migrate it will remove column and add column again to your table.
Hope it will help. Thanks.
Create another migration file with removed column list
def change
remove_column :account_number, :transaction_reference_number, :information_to_account_owner
end
Create one migration file with added column list
def change
add_column :mt940_batches, :created_by, :updated_by, :integer
end
Do not alter the create table migration file. Other wise data saved in the file will be lost.
If data lost is not important for you, then just remove the table using rake db:migrate:down version=<your migration file version>
And change the migration file
then run
db:migrate:up version=<your migration file version>
Suppose I created a table table in a Rails app. Some time later, I add a column running:
rails generate migration AddUser_idColumnToTable user_id:string.
Then I realize I need to add user_id as an index. I know about the add_index method, but where should this method be called? Am I supposed to run a migration (if yes, which one ?), then adding by hand this method?
You can run another migration, just for the index:
class AddIndexToTable < ActiveRecord::Migration
def change
add_index :table, :user_id
end
end
If you need to create a user_id then it would be a reasonable assumption that you are referencing a user table. In which case the migration shall be:
rails generate migration AddUserRefToProducts user:references
This command will generate the following migration:
class AddUserRefToProducts < ActiveRecord::Migration
def change
add_reference :user, :product, index: true
end
end
After running rake db:migrate both a user_id column and an index will be added to the products table.
In case you just need to add an index to an existing column, e.g. name of a user table, the following technique may be helpful:
rails generate migration AddIndexToUsers name:string:index will generate the following migration:
class AddIndexToUsers < ActiveRecord::Migration
def change
add_column :users, :name, :string
add_index :users, :name
end
end
Delete add_column line and run the migration.
In the case described you could have issued rails generate migration AddIndexIdToTable index_id:integer:index command and then delete add_column line from the generated migration. But I'd rather recommended to undo the initial migration and add reference instead:
rails generate migration RemoveUserIdFromProducts user_id:integer
rails generate migration AddUserRefToProducts user:references
Add in the generated migration after creating the column the following (example)
add_index :photographers, :email, :unique => true
For references you can call
rails generate migration AddUserIdColumnToTable user:references
If in the future you need to add a general index you can launch this
rails g migration AddOrdinationNumberToTable ordination_number:integer:index
Generated code:
class AddOrdinationNumberToTable < ActiveRecord::Migration
def change
add_column :tables, :ordination_number, :integer
add_index :tables, :ordination_number, unique: true
end
end
You can use this, just think Job is the name of the model to which you are adding index cader_id:
class AddCaderIdToJob < ActiveRecord::Migration[5.2]
def change
change_table :jobs do |t|
t.integer :cader_id
t.index :cader_id
end
end
end
For those who are using postgresql db and facing error
StandardError: An error has occurred, this and all later migrations canceled:
=== Dangerous operation detected #strong_migrations ===
Adding an index non-concurrently blocks writes
please refer this article
example:
class AddAncestryToWasteCodes < ActiveRecord::Migration[6.0]
disable_ddl_transaction!
def change
add_column :waste_codes, :ancestry, :string
add_index :waste_codes, :ancestry, algorithm: :concurrently
end
end
I need to remove a few columns from my rails model which i already created and have some row entries in that model.
How to do it? Any links which has details for modifying the schema in rails ?
I'm using rails version 3.
To remove a database column, you have to generate a migration:
script/rails g migration RemoveColumns
Then in the self.up class method, remove your columns:
def self.up
remove_column :table_name, :column_name
end
You may want to add them back in the self.down class method as well:
def self.down
add_column :table_name, :column_name, :type
end
The Rails Guide for this goes into much more detail.
If you know the columns you want to remove you can use the convention: Remove..From.. when naming your migrations. Additionally you can include the column names when running the migration command.
The form of the command:
rails g migration Remove..From.. col1:type col2:type col3:type
For example:
rails g migration RemoveProjectIDFromProjects project_id:string
generates the following migration file:
class RemoveProjectIdFromProjects < ActiveRecord::Migration
def self.up
remove_column :projects, :project_id
end
def self.down
add_column :projects, :project_id, :string
end
end
Via command alternative as Add, only change Add to Remove:
Single Column:
rails g migration RemoveColumnFromTable column:type
Multiple Columns:
rails g migration RemoveColumn1AndColumn2FromTable column1:type colummn2:type