PG::UndefinedTable error when running RSpec test suite in Rails 4 - ruby-on-rails

I have an RSpec test suite that tests many things including the creation of a model called CompanyReportByReturnOnCapital. The associated table used to be called company_report_by_return_on_capitals, due to Rails' automatic pluralization, and I've since run a migration to rename the table to company_reports_by_return_on_capital.
However when I run rake to run the test suite, I receive the following error:
1) StockReader#create_company_reports_by_roc creates reports
Failure/Error: CompanyReportByReturnOnCapital.delete_all
ActiveRecord::StatementInvalid:
PG::UndefinedTable: ERROR: relation "company_report_by_return_on_capitals" does not exist
LINE 1: DELETE FROM "company_report_by_return_on_capitals"
^
: DELETE FROM "company_report_by_return_on_capitals"
# ./spec/lib/stock_reader_spec.rb:102:in `block (3 levels) in <top (required)>'
My schema.rb:
ActiveRecord::Schema.define(version: 20141029193309) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "company_reports_by_earnings_yield", force: true do |t|
t.string "name"
t.string "symbol"
t.string "market_cap"
t.datetime "created_at"
t.datetime "updated_at"
t.string "ebit"
t.string "ebit_date"
t.string "enterprise_value"
t.string "earnings_yield"
t.string "fixed_assets"
t.string "working_capital"
t.string "return_on_capital"
t.string "market_cap_date"
t.string "total_assets"
t.string "total_assets_date"
t.string "current_assets"
t.string "current_assets_date"
t.string "total_debt"
t.string "total_debt_date"
t.string "cash_and_equivalents"
t.string "cash_and_equivalents_date"
t.string "working_capital_date"
end
create_table "company_reports_by_return_on_capital", force: true do |t|
t.string "name"
t.string "symbol"
t.string "ebit"
t.string "ebit_date"
t.string "market_cap"
t.string "market_cap_date"
t.string "working_capital"
t.string "working_capital_date"
t.string "total_assets"
t.string "total_assets_date"
t.string "current_assets"
t.string "current_assets_date"
t.string "total_debt"
t.string "total_debt_date"
t.string "cash_and_equivalents"
t.string "cash_and_equivalents_date"
t.string "fixed_assets"
t.string "enterprise_value"
t.string "earnings_yield"
t.string "return_on_capital"
t.datetime "created_at"
t.datetime "updated_at"
end
end
My migration files renaming the table:
class CreateCompanyReportByReturnOnCapitals < ActiveRecord::Migration
def change
create_table :company_report_by_return_on_capitals do |t|
t.string :name
t.string :symbol
t.string :ebit
t.string :ebit_date
t.string :market_cap
t.string :market_cap_date
t.string :working_capital
t.string :working_capital_date
t.string :total_assets
t.string :total_assets_date
t.string :current_assets
t.string :current_assets_date
t.string :total_debt
t.string :total_debt_date
t.string :cash_and_equivalents
t.string :cash_and_equivalents_date
t.string :fixed_assets
t.string :enterprise_value
t.string :earnings_yield
t.string :return_on_capital
t.timestamps
end
end
end
class RenameCompanyReportByReturnOnCapitals < ActiveRecord::Migration
def change
rename_table :company_report_by_return_on_capitals, :company_report_by_return_on_capital
end
end
class RenameReturnOnCapitalReports < ActiveRecord::Migration
def change
rename_table :company_report_by_return_on_capital, :company_reports_by_return_on_capital
end
end
Here is the test in spec/lib/stock_reader_spec.rb:
require 'spec_helper'
require 'stock_reader'
RSpec.describe StockReader do
describe '#create_company_reports_by_roc' do
before(:each) do
CompanyReportByReturnOnCapital.delete_all
end
it 'creates reports' do
StockReader.create_company_reports_by_roc($return_on_capital_array)
expect(CompanyReportByReturnOnCapital.count).to eq(2)
end
end
end
And finally, lib/stock_reader.rb where the actual code resides:
require 'csv'
require 'httparty'
module StockReader
def self.create_company_reports_by_roc(company_data_array)
company_data_array.each do |company|
CompanyReportByReturnOnCapital.create(
symbol: company[:symbol],
enterprise_value: company[:enterprise_value].to_s,
enterprise_value_date: company[:enterprise_value_date],
ebit: company[:ebit].to_s,
ebit_date: company[:ebit_date],
earnings_yield: company[:earnings_yield].to_s)
end
end
end
So far I've tried resetting the test database using the following commands:
RAILS_ENV=test rake db:drop db:create db:migrate, rake db:test:load, rake db:test:prepare
AND the development database using:
bin/rake db:drop and bin/rake db:create and bin/rake db:migrate with no success.
I'm out of ideas!
Just for good measure I'll include my model, app/models/company_report_by_return_on_capital.rb:
class CompanyReportByReturnOnCapital < ActiveRecord::Base
end
Thanks in advance

Something similar happened for me where PG was looking for a non-existent table which gave me errors when I tried to test.
I deleted the fixture file corresponding to the non-existent table and that solved the issue for me.

The problem was that I had to add inflections to my config/initializers/inflections.rb file so that Rails would not expect a table called company_report_by_return_on_capitals. Despite many db:drop's and migrations, Rails was still expecting this although company_report_by_return_on_capitals was nowhere to be found in my application. All's well now.

Related

When I run rails db:migrate the migration doesn't fully work

class CreateMessages < ActiveRecord::Migration[5.2]
def change
create_table :messages do |t|
t.text :body
t.integer :user_id
t.timestamps
end
end
end
After running rails db:migrate my schema looks like this...
ActiveRecord::Schema.define(version: 2020_03_20_063104) do
create_table "messages", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "username"
t.string "password_digest"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
I am wondering where the t.text "body" is and where the t.integer "user_id"is and why it isn't showing up in my schema under messages table.
I have checked migration status and all migrations have been ran.
If you ran something like this in your migration file
class CreateMessages < ActiveRecord::Migration[5.2]
def change
create_table :messages do |t|
t.timestamps
end
end
end
Messages table is created and after this you can't create another migration with create_table :messages. Like #Marek Lipka wrote on comments. Either you need to rollback your CreateMessages migration and chance file and run your migration again. Or you need to write another migration to change existing table like this.
class AddBodyAndUserIdToMessages < ActiveRecord::Migration[5.2]
def change
add_column :messages, :body, :text
add_column :messages, :user_id, :integer
end
end

How to add primary key to Rails?

I'm trying to make an e-commerce website type thing using Rails. So I've made my models for it. My problem is how to make a particular element a primary key?
create_table "bookmarks", :primary_key => bk_id force: :cascade do |t|
t.string "bk_name"
t.string "size"
t.string "brand"
t.string "product_id"
t.integer "mrp"
t.text "colour"
t.integer "stock"
t.integer "discount"
t.text "bk_description"
t.integer "bk_id", primary:true
t.integer "cart_unit"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
This is a portion of the schema.rb file. Is the way I've marked bookmark id as the primary key correct? Also, after making these changes, I ran rails db:migrate command and the primary key portion disappears and it becomes like this-
create_table "bookmarks",force: :cascade do |t|
t.string "bk_name"
t.string "size"
t.string "brand"
t.string "product_id"
t.integer "mrp"
t.text "colour"
t.integer "stock"
t.integer "discount"
t.text "bk_description"
t.integer "bk_id"
t.integer "cart_unit"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
I don't understand why this happened and why those changes I made (I did save the file after editing) just disappeared. Can someone explain this to me? Also, I'd like to mention that I'm learning Ruby on Rails so...please be gentle with me. :P
In your migration file:
create_table :bookmarks, :primary_key => :bk_id do |t|
...
t.integer :bk_id
...
end
Do not forget to indicate it in your Model too:
class Bookmarks < ActiveRecord::Base
self.primary_key = 'bk_id'
end
Assuming it’s Rails4+, you might do:
create_table :bookmarks, force: :cascade do |t|
...
t.integer :bk_id, primary_key: true
...
end
In Rails3 you just put an additional statement after:
create_table "bookmarks", force: :cascade do |t|
...
t.integer "bk_id"
...
end
execute "ALTER TABLE bookmarks ADD PRIMARY KEY (bk_id);"
Don't change content of schema.rb file. This content will be auto generated from your migrate files. Try find your create bookmarks migrate file and add :primary_key => bk_id to it.
File: db/migrate/xxxxxxxxxx_create_bookmarks.rb
(xxxxxxxxx is a timestamp)
Help it helps.

Heroku only one table being created - sinatra/ruby

so locally everything works fine. I have 2 simple tables in my DB, i have some migration files and everything. I've been trying to push to heroku for the past hour or so but it's not working. Only 1 table is being migrated, but the second one isn't. I tried creating other migration, but nothing works. Here's my schema:
ActiveRecord::Schema.define(version: 20140804004043) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "folders", force: true do |t|
t.string "name"
t.string "description"
end
create_table "ifolders", force: true do |t|
t.string "name"
t.string "description"
end
create_table "ifoldersx", force: true do |t|
t.string "name"
t.string "description"
end
create_table "images", force: true do |t|
t.string "name"
t.integer "folder_id"
t.string "description"
t.string "url"
end
end
I've tried heroku restart. heroku pg:reset DATABASE. but nothing is working.
Is there a way I can manually add the table into heroku, perhaps with command prompt or something?
Thanks!
EDIT:
Migration Files:
class CreateImages < ActiveRecord::Migration
def change
create_table :images do |t|
t.string :name
t.integer :folder_id
t.string :description
t.string :url
end
end
end
class CreateIfolders < ActiveRecord::Migration
def change
create_table :ifolders do |t|
t.string :name
t.string :description
end
end
end
class CreateIfoldersx < ActiveRecord::Migration
def change
create_table :ifoldersx do |t|
t.string :name
t.string :description
end
end
end
class CreateFolders < ActiveRecord::Migration
def change
create_table :folders do |t|
t.string :name
t.string :description
end
end
end
Make sure you are also re-migrating the database
heroku pg:reset DATABASE
heroku run rake db:migrate
If that doesn't work add your migration files into your question.
You can easily check if its working by starting up rails console on heroku
heroku run rails c
Edited...
Next step would be to jump in and see what the heroku logs are saying with heroku logs --tail and
$ heroku run rails c
File.open('log/production.log', 'r').each_line { |line| puts line }

new record in rails console error

A very similar question was already asked, bud I can't solve the problem anyway. I am trying to create a new record in rails console and I get this error:
2.1.2 :001 > subject = Subject.new
Mysql2::Error: Table 'simple_cms_development.subjects' doesn't exist: SHOW FULL FIELDS FROM `subjects`
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'simple_cms_development.subjects' doesn't exist: SHOW FULL FIELDS FROM `subjects`
Can somebody please very specifically tell my what should I do?
Here's subject.rb:
class Subject < ActiveRecord::Base
end
and schema.rb:
ActiveRecord::Schema.define(version: 20140617074943) do
create_table "admin_users", force: true do |t|
t.string "first_name", limit: 25
t.string "last_name", limit: 50
t.string "email", default: "", null: false
t.string "username", limit: 25
t.string "password", limit: 40
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "pages", force: true do |t|
t.integer "subject_id"
t.string "name"
t.string "permalink"
t.integer "position"
t.boolean "visible", default: false
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "pages", ["permalink"], name: "index_pages_on_permalink", using: :btree
add_index "pages", ["subject_id"], name: "index_pages_on_subject_id", using: :btree
create_table "sections", force: true do |t|
t.integer "page_id"
t.string "name"
t.integer "position"
t.boolean "visible", default: false
t.string "content_tipe"
t.text "content"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "sections", ["page_id"], name: "index_sections_on_page_id", using: :btree
end
create_subjects.rb:
class CreateSubjects < ActiveRecord::Migration
def up
create_table :subjects do |t|
t.string "name"
t.integer "position"
t.boolean "visible" :default => false
t.timestamps
end
end
def down
drop_table :subjects
end
end
Add a comma in
t.boolean "visible" :default => false`
as in
t.boolean "visible", :default => false`
and then run rake db:migrate
Making sure that config/database.yml file has a valid entry for a database connection on your machine. Look at the development stanza.
More on migrations at guides.rubyonrails.org/migrations.html
More on configuring a database and the database.yml file at
http://edgeguides.rubyonrails.org/configuring.html#configuring-a-database
You need to create a subjects table that defines the attributes you want to persist in the Subject instances.
So say you want title and description. Use this command to create the migration:
rails generate migration subjects title:string description:text
And then run the command
rake db:migrate
Then try your Subject.new command
Alternatively, if you do not want to persist any subject attributes, change the subject class definition to:
class Subject
end

Rails schema not changing

I'm trying to change a column called "description" in my table called "posts" to a .text rather than a .string so I can avoid getting errors for the value being too long.
I generated a new migration and ran rake db:migrate after having this:
class ChangePostsFormatInMyTable < ActiveRecord::Migration
def self.up
change_column :posts, :description, :text, :limit => nil
end
def self.down
change_column :posts, :description, :string
end
end
But the schema file doesn't show any changes and my column won't change. Am I missing something?
Schema:
ActiveRecord::Schema.define(version: 20140125221803) do
create_table "posts", force: true do |t|
t.string "description"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.string "title"
t.string "image"
end
end

Resources