I'm deploying an app for the first time and I am very confused. I'm using Fly.io with postgresql. It was working well until I added a migration "Add_cleared_boolean_to_trx".
I run #bundle exec rails db:migrate and/or #bundle exec rails db:migrate RAILS_ENV=production
I get the error
ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR: column "cleared" does not exist
I thought running db:migrate is what creates the column.
class AddClearedBooleanToTrx < ActiveRecord::Migration[7.0]
def change
add_column :trxes, :cleared, :boolean, null: false, default: false
end
add_index :trxes, :cleared
end
create_table "trxes", force: :cascade do |t|
t.date "date", null: false
t.integer "amount", default: 0, null: false
t.string "memo"
t.integer "account_id", null: false
t.integer "category_id", null: false
t.integer "vendor_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "cleared", default: false, null: false
t.index ["account_id"], name: "index_trxes_on_account_id"
t.index ["category_id"], name: "index_trxes_on_category_id"
t.index ["cleared"], name: "index_trxes_on_cleared"
t.index ["date"], name: "index_trxes_on_date"
t.index ["vendor_id"], name: "index_trxes_on_vendor_id"
end
My project repo: https://github.com/charleshug/moneyapp
Related
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 am making a notes app using Active Admin for the first time and I am running into an error that confuses me because the relationship exists my migrations are present as far as I can see in the schema. I have 2 models currently Note that belongs_to Content and Content has_many :notes . I am trying to customize my show for Contents so it will display differently as seen below but I keep getting a no method error for notes this relationship is present and should work as it is a foreign key between both tables?
class Note < ApplicationRecord
belongs_to :content
end
class Content < ApplicationRecord
has_many :notes
end
ActiveAdmin.register Content do
permit_params :name, note_ids: []
show title: 'Test' do
h3 'You have ' + pluralize(content.notes.count, 'note') + ' referencing ' + `#{content.name}`
end
ActiveRecord::Schema.define(version: 2021_05_06_140826) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "active_admin_comments", force: :cascade do |t|
t.string "namespace"
t.text "body"
t.string "resource_type"
t.bigint "resource_id"
t.string "author_type"
t.bigint "author_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["author_type", "author_id"], name: "index_active_admin_comments_on_author_type_and_author_id"
t.index ["namespace"], name: "index_active_admin_comments_on_namespace"
t.index ["resource_type", "resource_id"], name: "index_active_admin_comments_on_resource_type_and_resource_id"
end
create_table "admin_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", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["email"], name: "index_admin_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_admin_users_on_reset_password_token", unique: true
end
create_table "contents", force: :cascade do |t|
t.string "name"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "notes", force: :cascade do |t|
t.string "title"
t.text "body"
t.bigint "content_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["content_id"], name: "index_notes_on_content_id"
end
add_foreign_key "notes", "contents"
end
Are you sure that content is ActiveRecord object? It looks like it is instance of ActiveSupport SafeBuffer.
When i try to run heroku run rails db:migrate, i get the following error
Running rails db:migrate on ⬢ sharley... up, run.6479 (Free)
I, [2021-01-03T23:13:45.240708 #4] INFO -- : Migrating to AddTimestampToBlogs (20201225171213)
== 20201225171213 AddTimestampToBlogs: migrating ==============================
-- add_timestamps(:blogs, {:null=>true})
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::DuplicateColumn: ERROR: column "created_at" of relation "blogs" already exists
/app/vendor/bundle/ruby/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:47:in `exec'
/app/bin/rails:4:in `<main>'
Caused by:
PG::DuplicateColumn: ERROR: column "created_at" of relation "blogs" already exists
/app/vendor/bundle/ruby/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:47:in `exec'
/app/bin/rails:4:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
This is my schema file
Please, any help will be appreciated. Ive searched all over but to no avail.
ActiveRecord::Schema.define(version: 2020_12_29_225613) do
create_table "blogs", force: :cascade do |t|
t.string "name"
t.string "title"
t.string "content"
t.datetime "created_at", precenter code hereision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "user_id"
t.index ["user_id"], name: "index_blogs_on_user_id"
end
create_table "comments", force: :cascade do |t|
t.string "name"
t.text "body"
t.integer "blog_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "post_id"
t.integer "user_id"
t.index ["blog_id"], name: "index_comments_on_blog_id"
end
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", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "name"
t.integer "user_id"
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
add_foreign_key "comments", "blogs"
end
This is my add timestamps to blog file
class AddTimestampsToBlogs < ActiveRecord::Migration[6.1]
def change
add_timestamps :blogs, null: true
# backfill existing record with created_at and updated_at
# values making clear that the records are faked
long_ago = DateTime.new(2020, 12, 29)
Blog.update_all(created_at: long_ago, updated_at: long_ago)
# change not null constraints
change_column_null :blogs, :created_at, false
change_column_null :blogs, :updated_at, false
end
end
Is there anything else needed?
You could add add_timestamps(:blogs, {:null=>true}) unless column_exists?(:blogs, :created_at) && column_exists?(:blogs, :updated_at). It looks like someone deployed a migration to fix that before or something and now you're trying as well. With the conditional, it will only run the add_timestamps migration method if there are no created or updated at columns
UPDATE
In the migration add the conditional. With the conditional, it will only run that step if the timestamp columns don't exist. The issue is that you or someone on your team has run the migration on heroku before then possibly rolled back locally and then redployed. The db still has that change, hence the error you're receiving. So if you add the conditional, it will add the time stamp columns only if they already don't exist on that table
def change
add_timestamps :blogs, null: true unless column_exists??(:blogs, :created_at) && column_exists?(:blogs, :updated_at)
# backfill existing record with created_at and updated_at
# values making clear that the records are faked
long_ago = DateTime.new(2020, 12, 29)
Blog.update_all(created_at: long_ago, updated_at: long_ago)
# change not null constraints
change_column_null :blogs, :created_at, false
change_column_null :blogs, :updated_at, false
end
I'm developing a app on Rails to sell some products, with a table Users, a table Products and a table Reviews, where the users can write their own reviews on a given product; Now i'm starting to implement the payment system, starting with the monetize gem, but after i added the price field to the Product table and run rails db:seed, causes conflict with the Reviews table... Some advice needed. Present code goes like this:
product.rb
class Product < ApplicationRecord
has_one_attached :photo
has_many :reviews, dependent: :nullify
monetize :price_cents
include PgSearch
pg_search_scope :search_by_full_name, against: [:name]
end
review.rb
class Review < ApplicationRecord
belongs_to :user
belongs_to :product
end
schema.rb
ActiveRecord::Schema.define(version: 2020_11_11_190245) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "active_storage_attachments", force: :cascade do |t|
t.string "name", null: false
t.string "record_type", null: false
t.bigint "record_id", null: false
t.bigint "blob_id", null: false
t.datetime "created_at", null: false
t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
end
create_table "active_storage_blobs", force: :cascade do |t|
t.string "key", null: false
t.string "filename", null: false
t.string "content_type"
t.text "metadata"
t.bigint "byte_size", null: false
t.string "checksum", null: false
t.datetime "created_at", null: false
t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
end
create_table "products", force: :cascade do |t|
t.string "name"
t.string "description"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "price_cents", default: 0, null: false
end
create_table "reviews", force: :cascade do |t|
t.text "description"
t.bigint "user_id", null: false
t.bigint "product_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["product_id"], name: "index_reviews_on_product_id"
t.index ["user_id"], name: "index_reviews_on_user_id"
end
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", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "first_name"
t.string "last_name"
t.string "phone_number"
t.string "address"
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
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
add_foreign_key "reviews", "products"
add_foreign_key "reviews", "users"
end
Sometimes the error goes like this
"PG::NotNullViolation: ERROR: null value in column "product_id" violates not-null constraint"
Thanks for the help
I get the error with: heroku run rake db:migrate
Migrating to CreateResults (20150306174427)
== 20150306174427 CreateResults: migrating ====================================
-- create_table(:results)
-> 0.0479s
-- add_foreign_key(:results, :quantifieds, :users)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
no implicit conversion of Symbol into Integer/app/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.0.rc3/lib/active_record/connection_adapters/abstract/schema_statements.rb:707:in `[]'
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.0.rc3/lib/active_record/connection_adapters/abstract/schema_statements.rb:707:in `add_foreign_key'
I can't understand it because run rake db:migrate works.
class CreateResults < ActiveRecord::Migration
def change
create_table :results do |t|
t.string :result_value
t.date :date_value
t.belongs_to :quantified, index: true
t.references :user, index: true
t.timestamps null: false
end
add_foreign_key :results, :quantifieds, :users
add_index :results, [:user_id, :created_at]
end
end
class CreateQuantifieds < ActiveRecord::Migration
def change
create_table :quantifieds do |t|
t.string :categories
t.string :metric
t.references :user, index: true
t.timestamps null: false
end
add_foreign_key :quantifieds, :users
add_index :quantifieds, [:user_id, :created_at]
end
end
# encoding: UTF-8
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150306174427) do
create_table "days", force: true do |t|
t.integer "level_id"
t.integer "habit_id"
t.boolean "missed", default: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "goals", force: true do |t|
t.string "name"
t.date "deadline"
t.boolean "accomplished"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "goals", ["user_id", "created_at"], name: "index_goals_on_user_id_and_created_at"
add_index "goals", ["user_id"], name: "index_goals_on_user_id"
create_table "habits", force: true do |t|
t.datetime "left"
t.integer "level"
t.text "committed"
t.datetime "date_started"
t.string "trigger"
t.string "target"
t.string "reward"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "habits", ["user_id", "created_at"], name: "index_habits_on_user_id_and_created_at"
add_index "habits", ["user_id"], name: "index_habits_on_user_id"
create_table "levels", force: true do |t|
t.integer "user_id"
t.integer "habit_id"
t.integer "days_needed"
t.boolean "passed", default: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "quantifieds", force: true do |t|
t.string "categories"
t.string "metric"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "quantifieds", ["user_id", "created_at"], name: "index_quantifieds_on_user_id_and_created_at"
add_index "quantifieds", ["user_id"], name: "index_quantifieds_on_user_id"
create_table "relationships", force: true do |t|
t.integer "follower_id"
t.integer "followed_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "relationships", ["followed_id"], name: "index_relationships_on_followed_id"
add_index "relationships", ["follower_id", "followed_id"], name: "index_relationships_on_follower_id_and_followed_id", unique: true
add_index "relationships", ["follower_id"], name: "index_relationships_on_follower_id"
create_table "results", force: true do |t|
t.string "result_value"
t.date "date_value"
t.integer "quantified_id"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "results", ["quantified_id"], name: "index_results_on_quantified_id"
add_index "results", ["user_id", "created_at"], name: "index_results_on_user_id_and_created_at"
add_index "results", ["user_id"], name: "index_results_on_user_id"
create_table "taggings", force: true do |t|
t.integer "tag_id"
t.integer "taggable_id"
t.string "taggable_type"
t.integer "tagger_id"
t.string "tagger_type"
t.string "context", limit: 128
t.datetime "created_at"
end
add_index "taggings", ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], name: "taggings_idx", unique: true
add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context"
create_table "tags", force: true do |t|
t.string "name"
t.integer "taggings_count", default: 0
end
add_index "tags", ["name"], name: "index_tags_on_name", unique: true
create_table "users", force: true do |t|
t.string "name"
t.string "email"
t.text "missed_days"
t.text "missed_levels"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "password_digest"
t.string "remember_digest"
t.boolean "admin", default: false
t.string "activation_digest"
t.boolean "activated", default: false
t.datetime "activated_at"
t.string "reset_digest"
t.datetime "reset_sent_at"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
create_table "valuations", force: true do |t|
t.string "name"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "valuations", ["user_id", "created_at"], name: "index_valuations_on_user_id_and_created_at"
add_index "valuations", ["user_id"], name: "index_valuations_on_user_id"
end
UPDATE
Making these changes worked:
$ heroku pg:reset DATABASE
$ heroku rake db:migrate
class CreateResults < ActiveRecord::Migration
def change
create_table :results do |t|
t.string :result_value
t.date :date_value
t.integer :quantified_id
t.timestamps null: false
end
end
end
Thanks so much for your help! And for another perplexing question check this out: https://stackoverflow.com/questions/28863999/how-to-automate-into-method
t.belongs_to
Is invalid, you want either references or change it to integer and add _id to the field name. Then on your index add square brackets round the second and third arguments.