Postgres views not recognized by rspec - ruby-on-rails

Using Rails 3.2.18 and Postgres, I have a few tables for which I have created a view to minimize the data loaded by ActiveRecord. Everything appears to be running correctly when in the application, but when I try to run Rspec I get:
ActiveRecord::StatementInvalid:
PG::UndefinedTable: ERROR: relation "properties_view" does not exist
(where 'properties_view' is the view on the 'properties' table)
What can I do to ensure that Rspec loads views properly from Postgres?

Rails doesn't really understand "advanced" database concepts like views so they won't appear in your schema.rb. When rspec is setting up its test database, it will use schema.rb to create the database schema, since you won't find your views in schema.rb, you won't find your views in the test database that rspec will be using and everything falls apart.
The solution is to switch from schema.rb to structure.sql. You should be able to update your config/application.rb to say:
config.active_record.schema_format = :sql
and then do a rake db:structure:dump to generate the structure.sql file. Once you have that, remove schema.rb from your file system and revision control, add structure.sql, and try again.

If you don't want to switch to the SQL schema format, using the scenic gem may help (Scenic Gem Gitub).
They allow you to add SQL Views (also materialized) to migrations and also adds them to your ruby schema.
Worked for me like a charm.

Related

What generates the structurel.sql file in Rails?

I have 3 different schemas in one Rails application. My preparation of the test database using rake db:test:prepare fails with:
psql:/Users/me/myapp/db/structure.sql:7417: ERROR: relation "schema_migrations" does not exist
LINE 1: INSERT INTO schema_migrations (version) VALUES ('20131213203...
That's because it is not proper setting the Postgres search_path before doing all the insertions to the schema_migrations table. I haven't messed with this code in about 8 months and can't remember what I did. I haven't the faintest idea of how I even got those other schema to dump.
You may want to try rake db:structure:dump and / or rake db:schema:dump and try re-running rake db:test:prepare. The former should create the structure.sql and the later the schema.db
I was able to accomplish what I needed by doing two things:
Overriding the purge task under db:test in AR's railties to call a custom drop_database_objects method.
Using a little-known attribute in my database.yml: schema_search_path: public
The first thing lets me drop only the database objects I want, leaving my other support databases intact.
The second thing just creates the structure from my main database, and doesn't try to create the structure from the other databases. It looks like a bug in that it structure:dump doesn't set the schema search path appropriately at the end of the structure.sql script, right before the inserts into the schema_migrations table in a multi-schema instance. These fixes make that not necessary.

Rails rake db:schema:dump against SQL Server database with multiple schemas

The situation I have is that we have multiple schemas on SQL Server that we need to be able to do schema:dump and migrations against. One schema is for our new Rails application, the other schema is for a legacy system that we have dependencies on.
When running rake db:schema:dump our new schema tables are correctly created in the schema.rb file. The legacy schema tables do not end up in schema.rb. I'm wondering how others are dealing with this issue.
Another consideration I have given to this is since our legacy schema tables are fairly static would be to add these to a separate file once and then create a before hook for rake db:schema:load that would run that file prior to the schema.rb. Is there a before hook for rake db:schema:load; if so what is that?
Here is how I ended up solving this issue.
I added a before hooks into schema load and schema dump within hooks.rake as described below.
namespace :project do
namespace :db do
task :before_schema_load => :environment do
add_tables
end
task :before_schema_dump => :environment do
add_ignored_tables
end
end
end
Rake::Task['db:schema:dump'].enhance(['project:db:before_schema_dump'])
Rake::Task['db:schema:load'].enhance(['project:db:before_schema_load'])
Within the add_tables functionality I've manually created what is essentially a static schema.rb equivalent for my legacy tables since these will change infrequently (possibly never).
Within the add_ignored_tables I've added tables to the ActiveRecord::SchemaDumper.ignore_tables array to indicate tables that are outside of my schema that I don't want dumped to schema.rb. In my case this is everything that isn't under my current app's schema. In my situation everything that I want outside of my app's schema is specified within the add_tables so those tables as well should not end up in the schema.rb.
There is some material about multi-tenant databases using Postgres, the one I've referenced before is http://blog.jerodsanto.net/2011/07/building-multi-tenant-rails-apps-with-postgresql-schemas/. There is also a gem (https://github.com/influitive/apartment), which may also be inspiration, or even a solution for you.

Use migrations to setup test database in Rails 3

I have some raw sql statements that create triggers and functions in my migrations. They are not invoked in the tests.
How can I use normal migrations to setup the test database? And why isn't that the default method?
Reason is that the test database is restored from schema.rb file. And Schema dump doesnt create procedures,functions, fkeys etc. The reason for that is Rails doesnt encourage using them. You can however change the schema dump format to sql.
config.active_record.schema_format = :sql
See following thread Why does rake db:migrate in Rails not add functions to the schema file?
Check this article as well http://pivotallabs.com/users/jdean/blog/articles/1707-using-mysql-foreign-keys-procedures-and-triggers-with-rails

How to create schema in sql

As per http://edgeguides.rubyonrails.org/configuring.html and this post I have this in application.rb
config.active_record.schema_format = :sql
However, it's still creating db/schema.rb (even after I delete it) and more importantly it's not creating the schema in sql when I run "rake db:migrate". Anyone know what I'm doing wrong? I'm on Rails 3.1 pre.
Well, this could be a rails bug, but you can always generate your db structure with this:
rake db:structure:dump
This is going to generate an "#{Rails.env}.sql" file for you with your database structure in SQL.

Ruby on Rails Migration - Create New Database Schema

I have a migration that runs an SQL script to create a new Postgres schema. When creating a new database in Postgres by default it creates a schema called 'public', which is the main schema we use. The migration to create the new database schema seems to be working fine, however the problem occurs after the migration has run, when rails tries to update the 'schema_info' table that it relies on it says that it does not exist, as if it is looking for it in the new database schema and not the default 'public' schema where the table actually is.
Does anybody know how I can tell rails to look at the 'public' schema for this table?
Example of SQL being executed: ~
CREATE SCHEMA new_schema;
COMMENT ON SCHEMA new_schema IS 'this is the new Postgres database schema to sit along side the "public" schema';
-- various tables, triggers and functions created in new_schema
Error being thrown: ~
RuntimeError: ERROR C42P01 Mrelation "schema_info" does not exist
L221 RRangeVarGetRelid: UPDATE schema_info SET version = ??
Thanks for your help
Chris Knight
Well that depends what your migration looks like, what your database.yml looks like and what exactly you are trying to attempt. Anyway more information is needed change the names if you have to and post an example database.yml and the migration. does the migration change the search_path for the adapter for example ?
But know that in general rails and postgresql schemas don't work well together (yet?).
There are a few places which have problems. Try and build and app that uses only one pg database with 2 non-default schemas one for dev and one for test and tell me about it. (from thefollowing I can already tell you that you will get burned)
Maybe it was fixed since the last time I played with it but when I see http://rails.lighthouseapp.com/projects/8994/tickets/390-postgres-adapter-quotes-table-name-breaks-when-non-default-schema-is-used or this http://rails.lighthouseapp.com/projects/8994/tickets/918-postgresql-tables-not-generating-correct-schema-list or this in postgresql_adapter.rb
# Drops a PostgreSQL database
#
# Example:
# drop_database 'matt_development'
def drop_database(name) #:nodoc:
execute "DROP DATABASE IF EXISTS #{name}"
end
(yes this is wrong if you use the same database with different schemas for both dev and test, this would drop both databases each time you run the unit tests !)
I actually started writing patches. the first one was for the indexes methods in the adapter which didn't care about the search_path ending up with duplicated indexes in some conditions, then I started getting hurt by the rest and ended up abandonning the idea of using schemas: I wanted to get my app done and I didn't have the extra time needed to fix the problems I had using schemas.
I'm not sure I understand what you're asking exactly, but, rake will be expecting to update the version of the Rails schema into the schema_info table. Check your database.yml config file, this is where rake will be looking to find the table to update.
Is it a possibility that you are migrating to a new Postgres schema and rake is still pointing to the old one? I'm not sure then that a standard Rails migration is what you need. It might be best to create your own rake task instead.
Edit: If you're referencing two different databases or Postgres schemas, Rails doesn't support this in standard migrations. Rails assumes one database, so migrations from one database to another is usually not possible. When you run "rake db:migrate" it actually looks at the RAILS_ENV environment variable to find the correct entry in database.yml. If rake starts the migration looking at the "development" environment and database config from database.yml, it will expect to update to this environment at the end of the migration.
So, you'll probably need to do this from outside the Rails stack as you can't reference two databases at the same time within Rails. There are attempts at plugins to allow this, but they're majorly hacky and don't work properly.
You can use pg_power. It provides additional DSL for migration to create PostgreSQL schemas and not only.

Resources