How to Fix “Rails: UndefinedTable Error:relation … does not exist” Error in Ruby on Rails

Daniel Pericich
5 min readFeb 27, 2023

--

Photo by Ehimetalor Akhere Unuabona on Unsplash

You’ve gotten a ticket, or feedback from a client, that you need to be handling more data. This could be new tables to handle new data models, or updates to existing models. Either way, you start to write some database migrations and link together new model files.

When you go to add data, or even just check the existence of the table in rails console, you get a long stack trace error. The error says something about “Rails: UndefinedTable Error:relation … does not exist.” With this error you may see the name of the table that you are trying to call does not exist. Or, you may see a malformed table name that does not match the name spacing for your model.

This can be a frustrating experience, but it is not impossible to solve. In this article let’s look at three major causes for this error and how to quickly fix them.

Your Database Migrations are Out of Sequence

This first error cause is straightforward, but can be hard to track. It happens a lot when you have foreign keys in your new tables or models. Out of sequence refers to you referencing a table in one table creation call before that table exists.

Let’s say that we are setting up a storefront. We can have users who may have many orders. We keep track of who made the order by storing a user id on the order record. If we are not careful we may run a migration for an order with a reference to our user and get the error “Error:relation … does not exist.”

Figure 1. Orders table migraiton is called to reference a nonexistent users table.

The cause of this error should be obvious; we don’t have a users table. In order to successfully add our orders table to our schema, we first need to add all tables that it relies on. To have the correct database migration sequence, we will first run a migration to create our users table, then we can create our orders table:

Figure 2. An orders table migration is called after the users table has been created.

The Table Name, Model Name and Model File Name do not Match

For our second error, we need to return to the basics of Ruby on Rails. The Rails mantra is “convention over configuration.” If you follow the convention of table, file and model names, then Rails will do a lot of the heavy lifting of stitching your application together. It’s when you step away from convention that you get in trouble.

Once you’ve checked that your database migrations are in sequence, the next thing to check is that your model, file and table names all follow Rails convention. Say we are building a new schedule model that will be used in a warehouse. There are already some models for general schedules, but what we are making is specific to our warehouse operations.

To store our new logic, we may create a new “warehouse” directory to namespace our model. We want to add our schedules table, but we need to follow rails convention to make sure that everything works. There are three names that we will need to check to make sure we are following convention.

The first name we need to check is the SQL table name. Our database table name needs to be plural as a table is a collection of records. To include our name spacing for our warehouse specific table we will use the name “warehouse_schedules” within our database migration.

Our model file will be singular “schedule” and will be stored in our “warehouse” directory. The full path would then be “warehouse/schedule.” The final piece is our class name which will make use of our namespacing, but be singular just like the file it lives in. The output of this will be “Warehouse::Schedule.” To recap here is what we should have:

1) Table Name (plural) — warehouse_schedules

2) File Name (singular) — warehouse/schedule

3) Class Name (singular) — Warehouse::Schedule

If your migration sequences are correct, and your naming conventions are good then we can check the third and final common missing table name error.

You Need to Add a Module to Prefix the Table

Our final error is one of the easiest errors to fix, but one of the most frustrating errors to get. Your database migrations are in sequence and your naming for tables, models and files are in order. The issue here is that rails is forming your table name incorrectly.

What causes this? Usually when we have models that have heavy name spacing, caused by many subdirectories, we see that Rails has trouble forming the table name. Each layer of namespace you add should be reflected in your table’s name, but Rails does not always pick up when to add these table name segments.

To correct this, we will need to add a new file to our target directory. All model files that live in the warehouse directory will need to have the warehouse namespace. We have accounted for that in our class naming and our table names, but need to make use of a simple Rails helper method for the last name correction.

In the base of our warehouse directory we can add a warehouse.rb file which will store the table_name_prefix method. Inside the file we will have something like this:

Figure 3. We add a directory module to specify how to prefix individual model table names.

Notice that we are using a module instead of class as the warehouse value describes a collection of models, not a model itself. Within the module we call the class method table_name_prefix which explicitly sets the first part of our model’s table name. If we have a workers model then this prefix will direct Rails to look for a warehouse_workers table. In our case Rails will now know to look for warehouse_schedules.

Conclusion

None of the issues above are time intensive to solve, but do require general knowledge on Rails and Ruby. We’ve looked at general back end knowledge with the migration sequences, and then rails helper methods with prefix_table_name and the file naming conventions. I hope that this article was helpful for getting your backend and data layer fixed.

Notes

https://icelandcheng.medium.com/ruby-on-rails-using-table-name-prefix-and-namespace-to-organize-models-a08199deaa69

https://stackoverflow.com/questions/30290250/rails-pgundefinedtable-error-relation-does-not-exist

https://apidock.com/rails/ActiveRecord/Base/table_name_prefix/class

--

--

Daniel Pericich
Daniel Pericich

Written by Daniel Pericich

Former Big Beer Engineer turned Full Stack Software Engineer

No responses yet