How to create schema in sql - ruby-on-rails

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.

Related

Postgres views not recognized by rspec

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.

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.

Removing timestamp fields from the schema

I had used default generator to create some tables and they all had that t.timestamp in their definition so the schema that was created also has created_at and updated_at fields.
Now I am told that I don't need those two fields in my schema so I went to the original create_table* files and took out t.timestamp line from them and ran the db:migrate and schema:load commands
But still when I go to my schema.rb file I can see they are still there.
Is there anything wrong I am doing here?
Run
rails g migration remove_timestamps_from_table created_at updated_at
with table being your model's name. Since this is following the pattern remove x from y, rails is smart enough to generate the appropriate migration for you.
Then run
rake db:migrate
to update your development database and
rake db:test:prepare
to prepare the test database, and you're all set!
Read more on migrations here. If you are still having trouble, consider restarting your rails server or database server.

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

Create Sequence In Migration Not Reflected In Schema

I have an application that requires a sequence to be present in the database. I have a migration that does the following:
class CreateSequence < ActiveRecord::Migration
def self.up
execute "CREATE SEQUENCE sequence"
end
def self.down
execute "DROP SEQUENCE sequence"
end
end
This does not modify the schema.rb and thus breaks rake db:setup. How can I force the schema to include the sequence?
Note: The sequence exists after running rake db:migrate.
Rails Migrations because they aim toward a schema of tables and fields, instead of a complete database representation including stored procedures, functions, seed data.
When you run rake db:setup, this will create the db, load the schema and then load the seed data.
A few solutions for you to consider:
Choice 1: create your own rake task that does these migrations independent of the Rails Migration up/down. Rails Migrations are just normal classes, and you can make use of them however you like. For example:
rake db:create_sequence
Choice 2: run your specific migration after you load the schema like this:
rake db:setup
rake db:migrate:up VERSION=20080906120000
Choice 3: create your sequence as seed data, because it's essentially providing data (rather than altering the schema).
db/seeds.rb
Choice 4 and my personal preference: run the migrations up to a known good point, including your sequence, and save that blank database. Change rake db:setup to clone that blank database. This is a bit trickier and it sacrifices some capabilities - having all migrations be reversible, having migrations work on top of multiple database vendors, etc. In my experience these are fine tradeoffs. For example:
rake db:fresh #=> clones the blank database, which you store in version control
All the above suggestions are good. however, I think I found a better solution. basically in your development.rb put
config.active_record.schema_format = :sql
For more info see my answer to this issue -
rake test not copying development postgres db with sequences
Check out the pg_sequencer gem. It manages Pg sequences for you as you wish. The one flaw that I can see right now is that it doesn't play nicely with db/schema.rb -- Rails will generate a CREATE SEQUENCE for your tables with a serial field, and pg_sequencer will also generate a sequence itself. (Working to fix that.)

Resources