initially populate data in rails if database is empty from application - ruby-on-rails

I have created database migration, and migrated data both on development and production servers. I would like to populate database from the application, if it is empty and avoid rake db:seed and other similar methods. I know that it could be done through rake db:seed, but since application is already deployed I would not like to pollute deploy.rb for capistrano, or do it manually on both development and production.
Is there any hook on database open or initialization of Active Record where I can do something like
if !Pages.first
Pages.populate
end
I am aware of all recommended methods to populate database, but I would still prefer to do it from app.
Thanks

As you eluded to, this is not the best idea in the world, but maybe you could try using on of these approaches:
An initializer that will get called each time the rails environment is loaded.
Something in the config.after_initialize block. See http://guides.rubyonrails.org/configuring.html

Related

Ruby: Inserting records to existing rails database using non-rails script

I have a rails app that only allows users to search and view the contents of its (MySQL) database. To add records to the database, I'd like to run a ruby script automatically twice a day which generates the contents of the database and then updates the db. Is this possible, or does my script have to be a part of the rails web app?
Just to lead you in the right direction - you can use a Rake task for this. These are usually put in the lib/tasks directory.
It's a good idea to separate non-web related things such as seeding or updating a database. If this is a scheduled job, you can use whenever to hook the rake task to cron.
Solved this using rails runner command

Is there any chance of testing the PostgreSQL database in this scenario without duplicating the database in the development environment?

“I have a Rails application with PostgreSQL database. My database contains 1000 records in it.
I have written a rake task which will manipulate the records in the database.
If the rake task went wrong i want to revert back the changes to the original in the database.
is there any chance of testing the database in this scenario without duplicating the database in the development environment ?”
In Rails itself having the feature sandbox
If you wish to test out some code without changing any data, you can do that by invoking rails console --sandbox.
bin/rails console --sandbox
Loading development environment in sandbox
Any modifications you make will be rolled back on exit
irb(main):001:0>
You can paste your ruby code here and can see the changes you wanted to see. while closing this console, All your changes will be reverted back(running as a transactional)
For more informations you can refer this link
http://edgeguides.rubyonrails.org/command_line.html#rails-console
you can duplicate a database in same env.
create database test with template original_db;
Will create cop of existing db, on which you can run your tests, specifying test instead of original db name in connections string

how devise db:migrate works on production

I'm doing my first project on RoR I decided to use Devise gem for the authentication everything is working fine in Localhost, right now i'm able to sing_up, log_in, reset pass and some other default features that comes with devise.
What I don't understand is how everything gets setup once i push the project into production environment. Let me explain better.
-I see that devise generates db/schema.rb file based on the user.rb model that devise auto generate, these schema i assume needs to be created in the production db.
I have to push the project into git repo but..
1) How the code gets executed once is published
2) How the user table gets created
3) where do I need to specify the db connection (db, user, pass)
In general how is the process to migrate into production env?
I appreciate your help.
In rails db schema is controlled using migrations. Migrations are usually very small files living in db/migrations folder. Each of them defines a single subclass of ActiveRecord::Migration class.
Each migration is supposed to go both-ways, so it has to implement both up and down method (for rollback). In majority of the changes those are obvious (like when up action creates a table, down action should destroy it). For migrations like this you can use change function - rails will create down function automatically (assuming that all actions are reversible - some of the methods even accept extra arguments to make it possible like remove_column :table, :field, :integer. :integer bit might seem redundant here, however the action is irreversible without that information).
You run your migrations using db:migrate rake task. Effectively it will run all the migration which has not been run against current database. When it is done, it will dump your current database into db/schema.rb file. This file is used only as a snapshot of your current database schema, which is of great help if you need to get back to previous version of your application (which is why schema.rb should always be checked into your source control). It is also possible to recreate your database directly from that file rake db:schema:load, however it will cost you all your data.
If you check your database (any environment), you will notice there is one extra table called schema_migrations which does not appear in your schema file. This table contains all the migrations that has been executed against this database. This way rails will not retry migrations that already has been run.
There are many advantages of using migration system:
It is easy for every developer to bring their local database up to the latest schema.
It is easy to rollback your latest changes if deployment failed. (Not always the case)
So how to use it in production? You simply has to point the rake task to the right database:
RAILS_ENV=production rake db:migrate
You can find your database configuration in config/database.yml file. Note that this is the best practice not to store that file in source control and in case of production it is not advisable to store your database password there. Normally you will need to set it through environment variable.
It is important to remember couple of things about migrations:
Never, ever change the existing migration if there is a chance that someone has already run it. Especially, do not modify migrations that has run in production unless you are 100% sure what you are doing (for example fixing rollback). Since database remembers which migrations has run, it might lead to getting your local db out of sync with production db and hence lead to bugs.
Never ever change database schema manually - every change has to be made through migrations.
Well depending on where you're hosting your code you should still do a rake db:migrate to make the changes to the production DB.
If deployed on Heroku, run the following in the console:
heroku run rake db:migrate
Hope that answers your question?

Ruby on Rails and db:fixtures:load - can it ignore some models?

I have two databases in use in a Ruby on Rails application; one is the database for the application while the second is an independent database over which Rails is not given control.
Problem is when loading fixtures into the dev, it tries to run DELETE statements on the tables in the independent database from the connection to the dev database, which obviously errors out.
I don't want Rails to try to do ANYTHING but read the independent database - I especially don't want it trying to delete tables.
Is there a simple way to tell Rails to ignore the models for the second database when loading fixtures?
UPDATE: To clarify, Rails seems to think the tables from the independent database are part of the development connection, though I have specified the correct connection in the model class using establish_connection. As another note, all model classes work precisely as desired from script/console.
rake db:fixtures:load RAILS_ENV=testing
will do the job for database configured as testing in your database.yml
I think you might also be able to accomplish this by adding all the tables in the independent database to ActiveRecord::SchemaDumper.ignore_tables in environment.rb, like so:
ActiveRecord::SchemaDumper.ignore_tables = ['independent_db_table1', 'independent_db_table2']
Okay...my issue was that I used the script/generate to create the models from the secondary database, which also created fixture, schema, test, and migrations files. I had removed the schema, test, and migrations files, but did not remove the generated fixtures (they were empty files) as I did not think it had created any.
After removing all files (including the models) from the secondary database and re-running the migrations for the dev db, I added back only the model files and the database in databases.yml from the secondary db, which solved the issue.
I still can't explain why Rails' rake tasks were looking in the wrong database and I am a little disappointed with rails' addition of the schema_migrations table in the secondary database, which it obviously does not need.
However, it works now.
Delete the model_name.yml file in your test/fixtures directory and Rails will not try to delete these tables.
Better yet, delete all your *.yml files and stop using fixtures entirely.

Running DB Migrations from application

I have a rails application where each user has a separate database. (taking Joel Spolsky's advice on this). I want to run DB migrations from the rails application to create a new database and tables for this user.
What is the easiest way to do this?
Maybe the db migration is not the best for this type of thing. Thanks!
It would be nice if it could be a completely automated process. The following process would be ideal.
A user signs up on our site to use this web app
Migrations are run to create this users database and get tables setup correctly
Is there a way of calling a rake task from a ruby application?
To answer part of your question, here's how you'd run a rake task from inside Rails code:
require 'rake'
load 'path/to/task.rake'
Rake::Task['foo:bar:baz'].invoke
Mind you, I have no idea how (or why) you could have one database per user.
We use seperate configuration files for each user. So in the config/ dir we would have roo.database.yml which would connect to my personal database, and I would copy that over the database.yml file that is used by rails.
We were thinking of expanding the rails Rakefile so we could specify the developer as a environment variable, which would then select a specfic datbase configuration, allowing us to only have one database.yml file. We haven't done this though as the above method works well enough.
Actually I have discovered a good way to run DB migrations from an application:
ActiveRecord::Migrator.migrate("db/migrate/")

Resources