I've generated a scaffold and then migrated my database. After that, I destroyed my scaffolding and then generated scaffold again and try to migrate my database but I got an error that this table already exists. How can I delete that table from the database?
One other easy way to do so :
open rails console and use this command :
ActiveRecord::Migration.drop_table(:your_table_name)
If you haven't pushed your code then the solution given by #Cryptex Technologies works fine. But if you have(i.e if you are using version control) then i won't recommend that approach. In that case you should create a new migration something like this:
class RemoveTable < ActiveRecord::Migration[5.2]
def up
drop_table :table_name
end
def down
create_table :table_name do |t|
t.string :field_name_1
t.text :field_name_2
t.timestamps
end
add_index :table_name, :field_name_1, unique: true
end
end
To delete that table, you need to run the command
rake db:rollback
and if you want to delete the database of your current application.
then you need to run the command
rake db:drop.
Rails automatically generates migration, thanks to the command line generator.
For instance, if you want to remove the Users Table write a command line statement like this:
rails generate migration DropUsersTable
This will generate the empty .rb file in /db/migrate/ that still needs to be filled to drop the “Users” table in this case.
A Quick-and-Dirty™ implementation would look like this:
class DropUsersTable < ActiveRecord::Migration
def up
drop_table :users
end
def down
raise ActiveRecord::IrreversibleMigration
end
end
It’s “correct” as it shows that the migration is one-way only and should not/can not be reversed. But in order to make a truly clean job in case these modifications were to be reversed we need to have a symmetrical migration (assuming we could recover the lost data), which we can do by declaring all the fields of our table in the migration file:
class Dropusers < ActiveRecord::Migration
def change
drop_table :users do |t|
t.string :name, null: false
t.timestamps null: false
end
end
end
This can be long if the model is complex, but it ensures full reversibility.
Here again, changes will enter effect as usual after running rake db:migrate.
Related
Say I have an existing migration in Rails:
class CreateStudies < ActiveRecord::Migration
def change
create_table :studies do |t|
t.string :display_name, null: false
t.string :tag_name, null: false
t.timestamps
end
add_index :studies, :tag_name, unique: true
end
end
Later on I realise that I would like to populate this table with a number of rows and I don't want to use rake db:rollback or the seeds.rb file. What is the format of the new migration file?
Just:
At the command prompt generate:
rails generate migration AddInitialStudies
And modify up and down method of generated migration:
class AddInitialStudies < ActiveRecord::Migration
def up
Study.create(display_name: "Example name", tag_name: "example_name")
end
def down
Study.delete_all
end
end
At this point I generate one Study object, but you can add as many you want.
On down, remove records added on up, because rollback and migrate again will duplicate added records. I assume the only Study records are the created on up. Take care with :tag_name, which must be unique.
I suppose that it's better to use rake tasks to generate some new objects rather than using migration. Here is a sample code https://github.com/maxmilan/Adverts_desk/blob/master/lib/tasks/advert_generators.rake#L3. You can also send number of generated objects as argument of task.
In my db folder, I have two migrations that have do do with this. The first is a migration I created to drop a database I made earlier that did not have what I needed.
class DropProductsTable < ActiveRecord::Migration
def up
drop_table :freqs
end
def down
raise ActiveRecord::IrreversibleMigration
end
end
The second is the new database I created.
class CreateFreqs < ActiveRecord::Migration
def change
create_table :freqs do |t|
t.string :description
t.timestamps
end
end
end
The rake db:migrate works for development, but when I try to migrate Heroku, the error provided in the title occurs. What's happening? I have searched around StackOverflow to no avail.
First, "to drop a database" - not database, but table you mean, right?
Then, it's obvious that this table doesn't exist on Heroku. Try to skip first migration and migrate only second.
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>
First
ruby script/generate model Buyer id:integer name:string
after generating Buyer model, I did
rake db:migrate
it was working fine.
After 1 day I have executed below command
ruby script/generate model Seller id:integer seller_name:string
after generating Seller model, I did
rake db:migrate
I got an error, that Buyer table is already exists. why? we have different timestamp file.
class CreateBuyer < ActiveRecord::Migration
def self.up
create_table :buyer do |t|
t.string :name
t.text :description
t.decimal :price
t.integer :seller_id
t.string :email
t.string :img_url
t.timestamps
end
end
def self.down
drop_table :ads
end
end
and another one is
class CreateSellers < ActiveRecord::Migration
def self.up
create_table :sellers do |t|
t.integer :nos
t.decimal :tsv
t.decimal :avg_price
t.timestamps
end
end
def self.down
drop_table :sellers
end
end
I used Rails 2.3.11 and rake 0.8.7
Are you sure there were no errors generated when you ran the first migration? If an error is encountered while running a migration, the parts that were already run will still be in the database, but schema_migrations won't be updated with the migration timestamp. Therefore, the next time you try to run migrations, it'll try to re-run the first part of the failed migration, which will generate errors since it's already been run.
Updated: If you look in the error output you added (by the way, please add to the question rather than a comment, so it's formatted and the whole thing is included) you can see that the first Execute db:migrate is running the migration CreateBuyer. This confirms that your migration did not complete the first time you ran it or has since been unsuccessfully rolled back. To fix this, manually drop the buyer table, then rerun your migrations.
As a note, there's at least a couple issues in your CreateBuyers migration:
The table name should be buyers (plural) rather than buyer (singular)
The down part of the migration is dropping the table ads instead of buyers
The second problem there could explain why you're having trouble running migrations now, actually. If you rolled back the CreateBuyers migration, it would have dropped your ads table and left buyers in place.
Hey guys, when I first begin a rails project, the model user was designed and created. After all the migration part, it successful created the table "users" at postgres.
Well, then after doing some changes during the project, I realized that was missing an attribute/new column at the table.
So what I did was delete the table users from postgres and add a new column at my first migration ruby class:
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :name
t.string :password
t.string :email
t.string :authorization_token //this is the new attribute that I insert
t.datetime :created_at
t.datetime :updated_at
t.timestamps
end
end
def self.down
drop_table :users
end
end
So, when I run again the db:migrate hopping that a new user table will be created with the new attribute :authorization_token, it doesn't work, but with no errors.
(I know that I should not remove the table, there is another smart way to do it)
A tip for working with Rails -- do not hand modify your tables using SQL. When you saw the problem you should have written a new migration like #nruth showed. Running the rake:migrate command would have worked fine for you.
In this case since you've already deleted your 'users' table you now have the problem that your database schema is out of sync with what Rails thinks it is. To fix this problem you can either get the database schema to roughly match what Rails thinks it is by hand creating the 'users' table, running the down migration and then then the up migration. Or you can get Rails up to speed with the fact that the 'users' table no longer exists. Rails stores migration info in either a schema_info table (Rails < 2.1) or schema_migrations table (Rails >= 2.1). If you remove that table then Rails will think the schema does not exist and try to run all the up migrations and recreate the 'users' table for you again.
Lastly, over time you may accumulate a number of migrations that individually add a column or two that you forgot to include. If you haven't yet shipped or aren't in production yet, then you can write a migration that sort of baselines your table. It would look something like this:
class CreateBaselineUsers < ActiveRecord::Migration
def self.up
create_table :users, :force => true do |t|
t.string :name
...
This will forcibly drop the table and recreate it with all the attributes that you want.
Migrations are run once & stored in the database as having been used (take a look in the schema_migrations table). You could try using rake db:migrate:reset to re-run your initial migration, but it's better to just add new migrations (you won't want to blow away your database when it has data in it) as follows:
script/generate migration add_authorization_token_to_users authorization_token:string
which will generate something similar to the following:
class AddAuthorizationTokenToUsers < ActiveRecord::Migration
def self.up
change_table :users do |t|
t.string :authorization_token //this is the new attribute that I insert
end
end
def self.down
remove_column :users, :authorization_token
end
end
To see how add/remove column, change_table, etc work, take a look at ActiveRecord::ConnectionAdapters::SchemaStatements at http://api.rubyonrails.org or http://guides.rubyonrails.org/migrations.html