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?
Related
First part of my schema.rb
ActiveRecord::Schema[7.0].define(version: 2022_09_25_175429) do
create_table "book", force: :cascade do |t|
t.text "name"
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "genre"
t.index "\"tags\"", name: "index_formulas_on_tags"
end
As you can see, tags has escaped quotes in it. How do I fix this, and how did this happen in the first place? Actually, I'm now considering that this could be intentional, but I could of doubt it?
I have started my project with a Users table and have since migrated to using an Accounts table. In the process I have an old reference to the Users table still in my schema.rb file and I need to remove it and create a new reference, or update the reference.
I am trying to work out a migration that will allow me to do this, however it keeps throwing an error as there's no Users table and when it did exist, it never had an account_id , which you can see referenced in my schema.rb file.
I really just need my schema.rb file to update
"add_foreign_key "likes", "users", column: "account_id"
to
add_foreign_key "likes", "accounts", column: "account_id"
But am finding this impossible to do with a migration without generating an error.
Any suggestions?
ActiveRecord::Schema.define(version: 2022_01_18_013836) do
create_table "accounts", 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", precision: 6
t.datetime "remember_created_at", precision: 6
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "username"
t.string "first_name"
t.string "last_name"
t.index ["email"], name: "index_accounts_on_email", unique: true
t.index ["reset_password_token"], name: "index_accounts_on_reset_password_token", unique: true
end
create_table "likes", force: :cascade do |t|
t.integer "account_id", null: false
t.integer "product_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["account_id"], name: "index_likes_on_account_id"
t.index ["product_id"], name: "index_likes_on_product_id"
end
create_table "products", force: :cascade do |t|
t.string "product_name"
t.string "product_category"
t.string "product_type"
t.string "product_image"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.text "product_description"
t.string "product_country"
end
add_foreign_key "likes", "products"
add_foreign_key "likes", "users", column: "account_id"
end
Best way to resolve this is to create a migration that adds users back with only account_id then remove the foreign key, and drop the user table again.
Should be doable in 1 migration, however I went about it as follows.
I ended up creating a new Users table with just an account_id:integer
Created a migration to remove_foreign_key
Then created a migration to then drop that Users table again.
Schema file is looking correct now and I have all the migrations to trace my changes.
I've got two models Wallet and FakeWallet. The Wallet should have one FakeWallet and it should be identified through wallet_type and external_id. It means I need to add references based on wallets external_id field.
Standard migration will be:
# rails g migration addReferencesToFakeWallets wallet:references
class AddReferencesToFakeWallets < ActiveRecord::Migration[6.1]
def change
add_reference :fake_wallets, :wallet, null: false, foreign_key: true
end
end
After rails db:migrate produces me:
t.bigint "wallet_id", null: false
t.index ["wallet_id"], name: "index_fake_wallets_on_wallet_id"
How to bind these two models by external_id instead of wallet_id ?
[EDIT]
# schema.rb after suggestion from comments
create_table "fake_wallets", force: :cascade do |t|
t.decimal "balance", default: "0.0"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.bigint "external_id"
t.index ["external_id"], name: "index_fake_wallets_on_external_id"
end
create_table "wallets", force: :cascade do |t|
t.integer "wallet_type"
t.string "external_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
I am using ruby 2.7 and Rails version 6.0.2.1
When I try to test my model I get this message
Error:
OfferTest#test_valid_offer:
DRb::DRbRemoteError: PG::UndefinedTable: ERROR: relation "views" does not exist
LINE 8: WHERE a.attrelid = '"views"'::regclass
^
(ActiveRecord::StatementInvalid)
rails test test/models/offer_test.rb:4
This is my schema file:
ActiveRecord::Schema.define(version: 2020_01_20_105655) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "offers", force: :cascade do |t|
t.string "city"
t.string "area"
t.string "address"
t.string "contact_person"
t.string "contact_person_phone"
t.string "denomination"
t.string "category"
t.string "typology"
t.integer "guests"
t.integer "rooms"
t.boolean "lift"
t.decimal "expense"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "requests", force: :cascade do |t|
t.string "name"
t.string "last_name"
t.string "address"
t.decimal "budget"
t.date "date_of_request"
t.string "document_id"
t.string "phone"
t.string "residential_address"
t.date "date_of_birth"
t.string "notes"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "users", force: :cascade do |t|
t.string "name", null: false
t.string "last_name", null: false
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", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
end
Ad of now I have 3 tables. I am testing the Offer model but I get this strange behaviour.
This is my test model code
require 'test_helper'
class OfferTest < ActiveSupport::TestCase
test "valid offer" do
offer = Offer.new(city: "Rome", area: "Zona Sud", address: "Via Roma")
end
end
I've already run rails db:test:prepare but I cannot fix this issue.
My initial thought is that some gem is injecting behaviour into your models.
Something is expecting a table "views". The name views hints at either a gem using database views to virtualize tables, or some gem that works in the domain with views: for example a gem for statistics (An order has been viewed 21 times: has 21 views).
I'd suggest removing all gems from your gemfile and re-including them one by one. This will tell you what gem is injecting this behaviour: knowing what your dependencies do is an important part of building an app, IMO.
If it is a gem, that gem most probably has some migrations that you need to install and run:
bundle exec rake railties:install:migrations
bundle exec rake db:migrate
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.