0

Been working on this particular issue for a while and thought it was time to ask for help. I've had a look at the following links but no luck

PG undefinedtable error relation users does not exist

https://github.com/rails/rails/issues/3279

And my issue is somewhat similar to this https://github.com/rails/rails/issues/6470 but not exactly.

I have a class called type_tables which is the base class for the STI here is the schema for STI

create_table "type_tables", force: :cascade do |t|
 t.string "title"
 t.string "desc"
 t.string "type"
 t.string "uom"
 t.index ["title"], name: "index_type_tables_on_title"
 t.index ["type"], name: "index_type_tables_on_type"
end

Now, this type table is only a base class in my project and other types such as device_type, certificate_type etc inherit from it.

The model for type_table

class TypeTable < ApplicationRecord
  validates :title, presence: true, uniqueness: true
end

The other device_type model

class DeviceType < TypeTable
  has_many :certificates
  #this is where the error originates
  GARMIN_ID = find_by(title: "Garmin").id

  #when i use some constant value rails successfully executes the 
   db:create task in my rake file
  GARMIN_ID = 22

end

Now, here's the interesting bit, it only shows this behaviour the first time i,e when there is no existing table in my Postgres database. When I successfully create and migrate my application schema and when the tables are present this line will work everytime.

GARMIN_ID = find_by(title: "Garmin").id

My idea is that since it tries to find the column in the type_tables relation and the relation doesn't exist it throws a no relation exists error. Although the error you see on the console is

2018-08-07 02:24:49.281 UTC [69] FATAL:  database "myappdb" does not 
exist

mlcot_api | /usr/local/bundle/gems/activerecord-5.1.3/lib/active_record/connection_adapters/postgresql_adapter.rb:699:in 
`rescue in connect': FATAL:  database "myappdb" does not exist 
(ActiveRecord::NoDatabaseError)

When I create the db manually using

docker-compose run api rake db:create

And then run docker-compose up I get

ERROR:  relation "type_tables" does not exist at character 566

/usr/local/bundle/gems/activerecord- `async_exec': PG::UndefinedTable: 
ERROR:  relation "type_tables" does not exist 
           (ActiveRecord::StatementInvalid)
           WHERE a.attrelid = '"type_tables"'::regclass

NOTE: I know the work around and have my app working but I have a dependancy on a particular branch which has all of the commented code required to build my db for the first time which I want to remove.

Any help appreciated and thanks in advance.

evilGenious
  • 777
  • 5
  • 10
  • how about `docker-compose run api rake db:migrate` after `docker-compose run api rake db:create`? – Denny Mueller Aug 07 '18 at 03:29
  • Aborts the migration ` rake aborted! ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "type_tables" does not exist LINE 8: WHERE a.attrelid = '"type_tables"'::regclass ` – evilGenious Aug 07 '18 at 03:30

1 Answers1

0

It's a very bad idea to access your database while loading model definitions. Don't do that.

Instead, consider using a class method that only retrieves the value the first time it's needed:

def self.garmin_id
  @garmin_id ||= find_by(title: "Garmin").id
end

Personally I'd strongly discourage even that much persistence -- better to spend one query retrieving it fresh for each request that needs it -- but that's more a matter of design judgement.

matthewd
  • 4,332
  • 15
  • 21
  • Thanks for your help, but I am trying to understand why does the error occur in the first place? – evilGenious Aug 07 '18 at 05:07
  • Because you're accessing the database in your model definition, and the application wants to boot (including loading the model definition) before it does the DB work that creates the table. It's a chicken & egg problem. – matthewd Aug 07 '18 at 05:16
  • Exactly, that's why I was really troubled since I am new to rails. Thanks anyway. – evilGenious Aug 07 '18 at 05:24