random changes in schema.rb - ruby-on-rails

I've noticed this for months and I just didn't have the time to deal with it until now. Whenever my CI server does an automatic git pull and restarts the rails servers, the schema.rb gets randomly modified. As the example shows below, the api_name column of a certain table got dropped. I dropped this column about 3 months ago. Same with transportation_charges. And very often, the spacing in this file changes: see created_at and updated_at.
It's especially annoying since on the next run, when my CI does an initial git pull, it complains about changes to schema.rb and stops execution until they get pushed or reverted. And it's not just the CI server. I've seen this on other developer machines as well. Did anyone run into this before?
diff --git a/db/schema.rb b/db/schema.rb
index 470d3bf..166e3ee 100644
--- a/db/schema.rb
+++ b/db/schema.rb
## -883,7 +883,6 ## ActiveRecord::Schema.define(version: 20170720211740) do
create_table "ups_package_service_options", force: :cascade do |t|
t.string "name"
- t.string "api_name"
t.string "type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
## -910,9 +909,8 ## ActiveRecord::Schema.define(version: 20170720211740) do
t.string "code"
t.string "name"
t.string "api_name"
- t.decimal "transportation_charges"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
t.boolean "domestic"
end

When you run a migration, the schema gets updated not just by the migration, but also the current database. I'm guessing some of your developers are using databases inconsistent with the schema. Then you'll get unexpected changes every time they run a migration.

Related

can not create database when using "rails db:migrate" command

I am newbie with Rails and trying to make a very simple Rails program. My problem is, when I made a Rails program, at first, I had a mistake and created a database named image by this command rails g scaffold image video title star:integer description:text then I made this command rails db:migrate, when I realized that problem, I deleted image folder and create another folder named Course by this command rails g scaffold image video title star:integer description:text. Everything seem ok.
But, my problem is, when I tried this command rails db:migrate, I saw that nothing happen.
When I accessed the website http://localhost:3000/courses/new to try to make a new thing, I saw that I can not make anything new.
So, I think that maybe my problem is, I made the image folder before the course folder.
How can I work with this problem ?
Could you please give me some ideas ? Thank you very much.
#Juanse Gimenez here is my schema.rb, sorry for my shortcomings
ActiveRecord::Schema.define(version: 2021_01_08_042733) do
create_table "courses", force: :cascade do |t|
t.string "image"
t.string "video"
t.string "title"
t.integer "star"
t.text "description"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "images", force: :cascade do |t|
t.string "video"
t.string "title"
t.integer "star"
t.text "description"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
end
#borjagvo thank you for your comment, here is my new.html.erb <h1>New Course</h1> it is very simple, so I do not think that it is the reason ?

PG::DuplicateColumn: ERROR: column "product_id" of relation "users" already exists

I have seen this question posted several times and the solution is always to drop the database and recreate it. I have data in my database and hence do not want to do that.
Schema:
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "product_id"
end
My second to last migration file:
class AddProductIdToUsers < ActiveRecord::Migration[5.2]
def change
add_column :users, :product_id, :string
end
end
I have no other migration file that creates a product_id column on my current branch.
I have multiple branches with different database schema. I am wondering if that caused the issue. The branch that might have created the product_id is only there for reference now. It will not be merged to master.
How do I fix this issue? I have tried:
rake db:rollback step=3
rake db:migrate
but that did not work.
Your create_table is already creating product_id inside the database.
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "product_id" // <- note this line
end
And you are trying to add another column of same name in your table, which raises an error.

Why am I getting "PG::NotNullViolation null value in column "id" violates not-null constraint" whenever I login in my rails app?

After dumping, downloading and pg_restoring a DB from Heroku, any time I try to login in my rails application I get the above error.
It somehow seems that the user id is seen as nil (even though I can see an id value in the DB).
I also read that it may be due to the id being a simple int instead of a serial, however, as you can see in my schema:
create_table "users", id: :serial, force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "name"
t.string "last_name"
t.string "provider"
t.string "uid"
t.boolean "admin", default: false, null: false
t.boolean "affiliate_approved", default: false, null: false
t.integer "cart_id"
t.float "rev_share"
t.boolean "notice", default: false, null: false
t.string "iban"
t.string "piva"
t.string "invitation_token"
t.datetime "invitation_created_at"
t.datetime "invitation_sent_at"
t.datetime "invitation_accepted_at"
t.integer "invitation_limit"
t.string "invited_by_type"
t.integer "invited_by_id"
t.integer "invitations_count", default: 0
t.string "username"
t.string "slug"
t.integer "enrolls_count", default: 0
t.integer "partner_id"
t.string "country"
t.integer "referrer"
t.boolean "gdpr_marketing"
t.boolean "privacy_policy"
t.boolean "subscription", default: false
t.date "account_created_at"
t.boolean "profilazione"
t.boolean "terms_and_conditions"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["invitation_token"], name: "index_users_on_invitation_token", unique: true
t.index ["invitations_count"], name: "index_users_on_invitations_count"
t.index ["invited_by_id"], name: "index_users_on_invited_by_id"
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
t.index ["username"], name: "index_users_on_username", unique: true
end
And it seems that the id is used already as serial.
Do you have any idea of what may be going wrong? This application is live in production with a couple of thousands of users who aren't being impacted by this issue, which makes me think there's something wrong with my local PG setup.
Edit - full error message
PG::NotNullViolation at /auth/google_oauth2/callback
ERROR: null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null, 9367, 127.0.0.1, 2018-09-17 09:51:59.463125, 2018-09-17 09:51:59.463125).
Edit - more findings
In user.rb (the model file) there's an after_update hook where the following is executed:
def change_log
UserChange.create(ip_request: current_sign_in_ip, user: self)
end
This is so that we can track everything a user changes along with their IP (GDPR reasons).
After commenting that out, it all works alright and my user gets logged in as planned
There must be a callback to another table which is trying to persist with a null ID. Check for callbacks and the schema for any related tables. In your case this was the UserChange table.
I just had the same error after pulling a copy of the DB from Heroku:
PG::NotNullViolation: ERROR: null value in column "id" violates not-null constraint DETAIL: Failing row contains ...etc
It was happening every time I tried to create a new record. I'm guessing that when you log in, your app is creating a new record somewhere (possibly some login tracking/logging you are doing?) that is triggering the error. If you can't access the app through a web browser, you could try opening up the Rails console and see what happens if you try to create a new record directly. If you still get the error, the issue is not actually with your login but with your DB.
The issue for me was that I was using a different version of Postgres on my dev machine to the version on Heroku that created the dump file. After switching to the matching version of Postgres an re-pulling the DB, everything is working as expected again.
If you're using Postgres on Mac, when you add a new Postgres server, you can choose which version of Postgres it should use. You want to make your development and production environments as similar as possible so you definitely want to make sure that your DB versions match.

SchemaDumper generating different output on Mac & Linux

We're using activerecord 5.1.4 in our project.
When running migrations the SchemaDumper generates different output on different colleagues machines. Some are using Linux others using Mac.
We're all running the same postgres version 9.6
For example Macs generate:
create_table "appliances", force: cascade do |t|
t.string "brand"
t.integer "property_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Linux creates:
create_table "appliances", id: :serial, force: cascade do |t|
t.string "brand"
t.integer "property_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Linux output seems to have id: :serial and it doesn't pad columns to align.
It means we're constantly bouncing changes to schema.rb in version control
Why would the output be different?

Rake parallel:prepare changes schema

I'm using parallel_tests on a Rails 3.2 app and we have two developers, everytime I do a 'rake parallel:prepare' I get this change and it's the opposite for the other programmer.
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
+ t.datetime "created_at"
+ t.datetime "updated_at"
I really want rails to keep those constraints on and not try and remove them.
You or your colleague should reload schema (or all migrations) to database in development env.

Resources