Trying to db:migrate inside of heroku, migration is failing it - ruby-on-rails

So I have this migration inside of my Rails project:
class CreateSettings < ActiveRecord::Migration[5.2]
def change
create_table :settings do |t|
t.string :frequency
t.text :emails, array: true, default: [].to_yaml
t.integer :reorder
t.timestamps
end
end
end
The default value was originally failing it so I created another migration in order to remove that default value:
class ChangeDefaultColumnForSetting < ActiveRecord::Migration[5.2]
def change
change_column_default(:settings, :emails, nil)
end
end
The schema now looks good and that default value is gone but when I push it up to Heroku and run heroku run rails db:migrate, it fails at the original CreateSettings migration since it still includes the default value. Even if I remove that default value from the first migration manually, I get a "Expected 1 argument but got 0" error inside of Heroku.
Any ideas on how I can go about this? The migration works in development so it must just be a Postgres problem (as I'm using SQLite in dev).

A quick fix is to delete the ChangeDefaultColumnForSetting migration and edit CreateSettings to say:
t.text :emails, array: true, default: []
or
t.text :emails, array: true, default: nil
Then commit the changes and push to Heroku.
After that you really want to stop using SQLite if you're deploying on PostgreSQL. Developing on top of SQLite and deploying on PostgreSQL is going to cause all kinds of problems. You really need to develop, test, and deploy with the same database. Do yourself a big favor and install PostgreSQL locally so that you can test and develop with the same database that you're deploying with.
Alternatively, you could look at Rails.env in your migrations and run different code in different environments. But really, this is a bad idea.

Related

How to reset the id sequence of a Postgresql table on Heroku

I have a table 'entreprises' in my database which I filled by manually loading data using a thirds party application. As a result the id sequence is a all messed up and I get id=null error message when trying to create new records.
Heroku support recommended me to use: heroku pg:psql -a app_name, and go from there.
but I am not sure how to proceed from there actually. I tried : pg_set_serial_sequence('entreprises','id') but get an error as well: No Function Matches the given name and argument types....
I don t think it is a difficult task, not sure why Heroku support did not provide the full solution to the problem.
Connect to heroku console
heroku run rails c -app app_name
Run the following code
ActiveRecord::Base.connection.reset_pk_sequence!('entreprises')
Just log in to Postgres server or connect your database with pgadmin or any other Postgres GUI tool and run the following command in the query window.
truncate table entreprises restart identity
This will delete all the records from your table.
None of the solutions worked for me, especially not the one that could make me delete the entire table. I chose a different approach, which is passing all the table into UUID and save the old_id into a different table:
class ResetIdOfEntreprise < ActiveRecord::Migration[5.1]
def change
add_column :entreprises, :uuid, :uuid, default: "uuid_generate_v4()", null: false
add_column :entreprises, :old_id, :integer
Entreprise.update_all("old_id=id")
change_table :entreprises do |t|
t.remove :id
t.rename :uuid, :id
end
execute "ALTER TABLE entreprises ADD PRIMARY KEY (id);"
end
end

Ahoy gem created mutually exclusive migration?

I tried to learn new stuff and use Ahoy gem for my private project. While doing research online, I encountered one repo with Rails 4.2 and Ahoy 1.6 and one thing struck me. Then I started googling and it seems like it's not a single repo issue only.
class CreateVisits < ActiveRecord::Migration
def change
create_table :visits, id: false do |t|
t.uuid :id, default: nil, primary_key: true
(...)
rest of code omitted for readability
Am I missing something, or are those mutually exclusive lines? (not to mention primary key being nil by default?)
I ran almost the same migration locally (without Ahoy gem, with changed table name), and I got nicely-looking db/schema.rb (at first glance - no errors yet), but of course when I try create new object, I hit ActiveRecord::NotNullViolation: PG::NotNullViolation: ERROR: null value in column "id" violates not-null constraint error
In my opinion, I'd have write something like this to make it work, or am I missing something really important here that blocks me from persisting an object in DB?
class CreateVisits < ActiveRecord::Migration
def change
create_table :visits do |t|
t.uuid :id, primary_key: true
(...)
Seems like this thing was not related to this Gem, but to other Dev running migration outside Rails migrations and not letting anyone know. This created some confusion between environments.

Rails schema dump is putting string in for postgres point.. How do I fix this?

I have a POINT defined in my migrations... when I run the migrations I get a POINT in my database.. Perfect!! Just exactly what I asked for.
But.. What I see in schema.rb is t.string? This messes up my CI system, because it builds the database based on the schema.rb.
Now my co-worker wants to change the type in the database to array, because it would be easy. I find that leaves a stink in my code.
Q: How do I make the schema.rb file show the column as a point?
For completeness
/20141120 ... .rb
class AddHeaderToUser < ActiveRecord::Migration
def change
add_column :users, :header_image_centre, :point
end
end
/schema.rb
t.string "header_image_centre", limit: nil
This seems to be fixed in Rails 4.2

Heroku db:migrate error, removed index

New to rails and having some Heroku troubles. I created a table and with it an index. I needed to change a field name, and naturally the index goes with. So I created three migrations, one to remove the field, the next to remove the index, and the last to add both. My computer has no issues handling this migration, but Heroku fails.
I have tried merging migrations #1 and #2 into one migration, but had no luck with that.
Index name 'index_updateresults_on_env_id_and_created_at' on table 'updateresults' does not exist/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/schema_statements.rb:825:in `index_name_for_remove'
Edit:
May as well add my migrations.
class CreateUpdateresults < ActiveRecord::Migration
def change
create_table :updateresults do |t|
t.string :content
t.integer :env_id
t.timestamps
end
add_index :updateresults, [:env_id, :created_at]
end
end
class RemoveEnvIdFromUpdateresults < ActiveRecord::Migration
def change
remove_column :updateresults, :env_id, :string
remove_index :updateresults, [:env_id, :created_at]
end
end
class AddEnvNameToUpdateresults < ActiveRecord::Migration
def change
add_column :updateresults, :env_name, :string
add_index :updateresults, [:env_name, :created_at]
end
end
Edit 2
I'm at a loss. It seems as though in Postgre, removing a field also removes any indexes on that field. This may not happen in SqlLite, hence why my local environment works but Heroku breaks (just a guess). I've tried deleting the migration that removes the index to hopefully avoid this issue, I've committed the change, and pushed it to Heroku. Yet I'm still getting the same error, and when I clone the repo the migration still exists. Maybe this is something Git related and less Rails related.
Found a lot of information at this other question. I ended up being right in that it was git related. Completely unsure why my commits that were deleting the file, weren't taking place on Heroku. I ultimately did a git rm commitname, then heroku push -f to my repository. It finally took at this point.

how i can i check the existence of the table

hy
A lot of time when i run rake db:migrate i get an error because the table user or foor or bar exist.
I try to check the existence of table, but that didn't work and i dont know why .
I use rails 3.2.2
class AddDeviseToUsers < ActiveRecord::Migration
#def self.table_exists?(users)
# ActiveRecord::Base.connection.tables.include?(users)
#end
if !table_exists?("users")
def change
create_table(:users) do |t|
## Database authenticatable
t.string :email, :null => false, :default => ""
t.string :encrypted_password, :null => false, :default => ""
end
end
end
You can check the existence of a table with the following command. This question has already been posted and answered here.
ActiveRecord::Base.connection.table_exists? 'users'
However, your code contains errors. You cannot define a method inside an if block with the syntax you're using. Put the block inside your method, instead.
def change
if !table_exists?("users")
# ...
end
end
Also, you should not be getting this kind of errors often, as you state. Migrations are applied sequentially. Creating your users table in a separate migration before adding Devise to it would take care of that problem. If you run into this problem while migrating an existing project from scratch, consider using rake db:schema:load instead.
In your command terminal type in
sqlite3 db/development.sqlite3
then you can search through your database by SQL command. Use .tables to list all tables in the database and you can see if yours is missing or not.
You can also just look at your schema file to see if the migration worked. The table along with all of it's attributes will be listed there.
You should never have multiple migrations that both try to create the same table. You also should not experience errors like this if you're working with rails migrations correctly.
The way rails migrations work is that every time you run rake db:migrate, for every migration file that runs successfully, it stores the number part of the migration file 123456789_create_users_table.rb (123456789 in this case) in a table in your db called schema_migrations. This way if a migration has already been run, it will never get run again.
It doesn't sound like you're working with rails migrations correctly. I suggest reading this thoroughly: http://guides.rubyonrails.org/migrations.html

Resources