rails db:migrate not working - ruby-on-rails

I had a controller that I misnamed and ended up removing it from the command line via rails destroy controller. I ended up recreating everything but every time I have run rails db:migrate I get the following error.
SQLite3::SQLException: table "advertisements" already exists: CREATE TABLE "advertisements" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar, "copy" text, "price" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)
I'm at a loss in terms of what to do, I've been dealing with this one tiny mistake for the last two days and everytime I seem to get on the right track one, yep. If anyone can tell me why this error is happening and what I can do I would greatly appreciate it. Thanks in advance

Take a look at the db/migrate directory. Could it bee that you have two xxxxx_create_advertisements.rb files (where xxxxxx is a bunch of numbers, more precisely the timestamp for when this migration was created)?
If so, then remove one of them (if both have the same column definitions then it does not matter which one - unless you have foreign key dependencies).
And then try again.

The issue is because your 'destroy_controller' command somehow didn't delete the table 'advertisements'. There are 2 solutions :
If you do not have any changes in the table then you don't need to recreate the table. Just comment out the migration in which you are creating table advertisements table.
If you really want to re-create the table then add drop_table :advertisements in your migration before creating the table, this will delete your existing table and then continue with the migration.
You can find the migration in db/migrate/ folder with name like 'xxxxx_create_advertisements.rb'

You should add a migration that drops the advertisements table.

Related

How to keep track of a table data-change migration on Ruby on Rails

Here is the problem:
I have Ruby on Rails project that has a table that have almost 100k rows and I have a binary column and I want to make changes in the content data on this column.
So I must iterate over those 100k rows, making changes on that row on particular column, saving it back on database.
But I must keep track of changes because these changes could fail and I should have someway to re-start data change from where I stopped.
Here is what I thought of a way of doing it:
Create a Migration to have a table MigrationTrack to track all records that have being migrated
Create a model of the above migration
Create a rake task that grabs all 100k from TableToUpdate and iterate over them, saving data back to row and save its ID on MigrationTrack. Create a logic to have a join on TableToUpdate and MigrationTrack to filter only ids that I haven't updated yet
After above migration finished create another migration to drop MigrationTrack table and remove its model.
Is there any other "Railsh way" to do that? Anyone have done such change?
Thanks
I would do it like this:
Add and deploy a migration adding a new column with the desired data type to the database table.
Add code to your model that save the value from the old column into the new column too.
Run a rake task or a simple one-liner in the console that touches all records to make sure the code introduced in step one ran on each record.
After this step, you can manually verify if all records in the database have both columns set as expected.
Switch using the new attribute instead of the old attribute in the code.
Drop the old column.
For simple cases, try running a simple view to check how it will turn out to be, for example, if your migration is
change_column :table, :boolean_field, 'integer USING CASE boolean_field THEN ...'
then you try do a simple select query with your cast, if you need more safey, you can create 'up' and 'down' methods on your migrations, then you can create a backup table on up, and on down, you can revert the values

table which has been dropped before - create migration again

Question regarding migration:
I had a table a few months ago called payment
then we wrote a migration and dropped it
now I want that payment table again
I generated a migration but when I migrate it actually drops and does not create payments.
Please, can someone give me direction? TA
It depends on how you dropped your table.
How Migration Works
Whenever migration is created, it has its own timestamp & when you run rake db:migrate, it will run up method (create table in your case) & store timestamp of that migration in schema_migrations table.
You can check whether payments table present or not in your database by using following,
ActiveRecord::Base.connection.tables.include? 'payments'
case - If you have dropped table not by rails migration (by console or external source), Then schema_migrations will not clear timestamp of migration which create payments table (running down method can clear timestamp). but adding new migration for creating payments table with new timestamp will not affect you.
And if still it does not help, it all depends on what you have written in your 'create payment table' migration file, method invoked inside it must be change or up (additional info).

Recreating a table in Rails

I'm using Rails and Postgres. I currently have a Like table created. I need to drop this table and re-create it. Here's what I've done so far.
1) Rename create_likes migration file to create_likes_old so there is no conflict with file names within migrations.
2) Change the name of the table inside the migration from create_table :likes to create_table :likes_old.
3) Generate new create_likes migration that creates a table called Like.
Currently I'm running into the following issue when I run rake db:migrate:
PG::DuplicateTable: ERROR: relation "likes" already exists
This makes it seems like the Like table was never renamed to LikeOld. What's wrong and how do I fix this?
Old migrations don't run when you change their content, and you should not rename them. Even if they did run, changing the create_table :likes to create_table :old_likes cannot possibly change the name of an existing table. That isn't what create_table does. At best, re-running that migration will now cause a new table to be created called old_likes, with no content, while leaving your old likes table unaffected. In actuality re-running that migration will simply fail, as it will attempt to undo the migration first, dropping the table old_likes which does not yet exist.
What you need to do is create a new migration called rename_likes_to_old_likes, which actually renames the table, using rename_table. Then, either:
delete the old migration entirely, so you can introduce a new migration with the same name
OR
create a new migration with a unique name such as create_new_likes_table or the like, and introduce your new table there.

Rails on heroku: after push, get "PG::UniqueViolation: ERROR: duplicate key value violates unique constraint"

This has been asked several times before (here and here, and more).
Every time I push my rails app to Heroku (for at least the last few months, I'd say), I have to reset my keys using the familiar
ActiveRecord::Base.connection.tables.each { |t| ActiveRecord::Base.connection.reset_pk_sequence!(t) }
incantation. Otherwise I get postgresql failures like this when I try to create new records:
PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "users_clients_pkey" DETAIL: Key (id)=(401) already exists. : INSERT INTO "users_clients" ("user_id", "client_id") VALUES (20, 46) RETURNING "id"
(This is an example; it happens on various tables, depending on what the first action is that's done on the app after a push.)
Once I do the reset-keys incantation, it's fine until my next push to heroku... even when my push does not include any migrations.
I'm a little baffled as to why this is happening and what can be done to prevent it.
No, there's no datatable manipulation code in my deployment tasks.
Its happening because the primary key(id) value already exists. Why? Because the primary key sequence in postgres is messed up. without looking at the database or knowing the schema, it difficult to suggest a solution but if your database can affort a downtime of 10-15mins. you can try
If there is just one table which is problem. you can Export all data into new set of table with new names without ID column.
drop existing tables and rename the newly created table to old tables's name.
enable writes to our app again.
But if entire DB is in a mess, then it need something more elaborate but I can't tell without looking the schema.

Rails - updating a model data members

I wanted to know what is the right way to update a Model.
for example, suppose I want to change a name of a data member from likes to numOfLikes.
this variable appears in the Model itself, but also in schema.rb and in db\migrate\XXX.rb
I changed manually those files and got this error:
undefined method `numOfLikes' for # Topic:0x3442d88
So, what is the right way doing it? (I am also asking about deleting a data member or adding one)
The best way is to run a migration to rename the column, which will update the schema.rb file.
You shouldn't be editing schema.rb directly, and the migration file only runs commands on the database, not affect the model if changed once run.
Schema.rb represents the state of the database schema, it doesn't control or change it by changing the contents of the file alone.
A new migration that contains:
rename_column :table_name, :likes, :numOfLikes
This will rename the column in the database, and will dump the database schema into schema.rb with the new attribute name.

Resources