Automating Rails workflow? - ruby-on-rails

When working with Rails, is there any way to customize the results from rake commands?
For instance, I use the rake dump task - rake db:dump - so that it gets all my locally produced database entries. I would want to expand that to a deployed app so that I can run one command and have a file that can reproduce my DB.
How can this be done?

What you could do is write a bash script that is just all the commands you need to dump and deploy.
You can also create an alias that runs multiple commands, which might be closer to what you want to do.
Here's a similar question that has answers explaining both:
How can I define a bash alias as a sequence of multiple commands?

Related

Google App Engine: Ruby on Rails - Execute migrations automatically

I was wondering if it was possible to run migrations automatically during deployment with Google App Engine. I have been using AWS Elasticbeanstalk for a while and they were ran automatically but now I am considering moving to the Google App Engine for my future projects.
Right now, I must run this command manually:
bundle exec rake appengine:exec -- bundle exec rake db:migrate GAE_CONFIG=app.yml
Thank you
WARNING: As discussed in comments, there is a race condition in migrations if deployment is done on multiple containers in parallel, because it will try to run migration on all containers. Solution is being discussed in comments, i will update this answer when we land on something.
Disclaimer: This answer is not exactly what was asked for, but it solves same problem and it works. And from what i can tell from question, doing it with some appengine config is not a requirement, rather he just want the migrations to run automatically.
I will expand on my comment on question, here is something i tried and it works. I am strong believer of KISS(keep it simple and stupid). So instead of trying to figure out appengine(which i have never used anyway) if i were you, i would take a generic approach. Which is, to plug into rails server booting process and trigger migrations. For this we have multiple approaches.
With my understanding of appengine and suggested by this official doc link appengine has a app.yaml file, this file has an entry something like:
entrypoint: rails server
So we will use this entry point to plug in our code to run migrations before starting server. For this i did this:
Make a new file in bin directory, i named it
rails_with_migrations.sh you can name it whatever you like.
Give it execute permissions with chmod +x bin/rails_with_migrations.sh
Put this code inside it:
#!/bin/bash
bundle exec rake db:migrate
bundle exec rails $#
Of course you can give whatever RAILS_ENV you want to give these.
Now in app.yaml on the entrypoint section, instead of rails server give it bin/rails_with_migrations.sh server and it should be it. It worked on local, should work everywhere.
NOTE: In entrypoint: i have bin/rails_with_migrations.sh server here, server is rails command parameter, you can pass as much parameters as you like these all will be passed to rails server command with $#'s magic. It is there to allow you to pass port and any other parameters you may need to provide for your environment. Also it allows you to run rails console locally with bin/rails_with_migrations.sh console which will also cause migrations to get triggered.
UPDATE1: As per comment, i checked what happens if migration fails, and it starts server even if migration fail. We can alter this behavior of-course in our sh file.
UPDATE2: The shell-script with migration error code handling will look something like:
#!/bin/bash
bundle exec rake db:migrate
if [ $? -eq 0 ]
then
bundle exec rails $#
else
echo "Failure: migrations failed, please check application logs for more details." >&2
exit 1
fi
This update will prevent server from starting and causing a non zero exit code from the script, which should indicate that this command failed.

Rails 3 Create Script to Manipulate My DB

I'm trying to create a script to mess around with the db entries in my rails application, but I don't know how to properly set it up to gain access to all my models etc.
I can do this easily with scripts like seeds.rb using 'rake db:seed' to execute or in my application controllers, but I want to create scripts outside of these that I can run in the background or just once.
Do I need to include something, or call the script with a certain rails command? And as a second related question, is there any way for me to execute rails commands like 'rake db:seed' from within a ruby script? The only method I know of right now that works is running 'rails console' and executing commands there.
require 'config/environment.rb'
When the script is in your rails root...

Use linux script to make a continuous rake task running (start, stop etc)

I have a rake task which parses a streaming API and enters data into database. The streaming API is live feed and the rake task should run continuously for the live data to enter the database. The rake task once called will run continuously and parse the data. Now i have started the rake task and it is running. The problem is that if i close the terminal or reboot the server, the rake task wil be stopped. So, i want a script in linux (something like the one used to start, or stop apache server), which does the following:
1. start the rake task by calling rake command (rake parse:stream) from the RAILS-ROOT (application directory of Rails app)
2. stop the rake task by killing the process.
3. start the rake task automatically when the server reboots.
i am not familiar to linux scripts and i dont know where to start. i am using ubuntu server. can anyone help me?
Here's an article that might help you also. It discussed various options for managing Ruby applications and their related processes:
http://michaelvanrooijen.com/articles/2011/06/08-managing-and-monitoring-your-ruby-application-with-foreman-and-upstart/
You need to run your script as a daemon. When I create this kind of startup scripts I usually make 2 files, one that stays in /etc/init.d and handles the start/stop/status/restart commands and another one that actually does the job and gets called by the first script.
Here is one solution, and although the daemon script is written in perl, you want to run some command lines only, so daemonizing a perl script could do your job easily.
If you want, there are also ruby gems for daemonizing scripts, so you can write a script in ruby that does the rake tasks.
And if you want to go hardcore, there are solutions for writing bash scripts that can daemonize, but I'm not sure I would recommend a solution like that; at least I find them pretty difficult to use.
Take a look at how Github's Resque project does it.
Essentially they create tasks for starting/restarting/stopping a particular task, in this case resque:work. Note that the restart_workers task simply invokes the other tasks, stop and start. It should be really easy to change this for what you want.

Expose Rails App Environment to Ruby Script

Out of pure curiosity, I am wondering if it's possible (no doubt it is) to 'hook into' a Rails Application's environment. So for example, say I want to create a cron script (I don't) that operates some sort of maintenance on a Rails app, and I want to write it in Ruby and using all of the nice code that I already have, for example, User.find etc.
Is this possible, and if so, how?
I'm just curious, as I feel I would eventually want to do this for some reason or other.
I'm currently on Rails 3 with Ruby 1.9.1, in case it matters.
This is certainly possible. Here is a good writeup on how to do that: How to run a rake task from cron
Take a look at the Rails::Railtie class. If you need to run code code when you start up your app, this is a way to do it. Here's a very simple example.
From the beginning of Rails there is ./script/runner, designed exactly for such kind of problems.
In Rails 3 you call it as: ./script/rails runner "puts User.find(:all).map(&:inspect)"
Try ./script/runner --help or ./script/rails runner --help
As the argument to the runner you provide a filename or just a code.
It's often more useful than preparing a Rake task, because you can execute just one-time actions:
ssh prod#example.com "cd rails/app && ./script/runner -e production 'puts User.count'"
You could either use script/rails runner as suggested by Arsen7 or you could write your own script in which you load the app environment in the beginning:
require 'config/environment'
is actually everything you need.
To have your script working in a cron job, make sure that it is executable (chmod u+x) and that it starts with a correct shebang line (#!/usr/bin/env ruby or whatever is appropriate for your situation).
yeah just require these file at top of your script file
require 'config/boot.rb'
require 'config/application.rb'
Rails.application.require_environment!
Now you'll have access to your models

Running Rake Without Shell Access?

For a RoR installation, is there any way to run rake commands without root access?
To put it another way, is there any way to get db:create and db:migrate to be run without root access (perhaps automatically or something)? Or can I run rake commands from a RoR controller?
Take a look at rails-2.X.X/lib/tasks/databases.rake and you can see the code called to create, drop, and migrate your database.
Once a rails environment is initialized, you can use the code inside the rake task file to create, drop, and migrate.
I do not know if you can do this at the controller level before it errors, but you can always try. You could also do it after rails has finished initializing in the environment file.
config/environment.rb
...
ActiveRecord::Migration.verbose = false
ActiveRecord::Migrator.migrate(File.join(Rails.root, 'db', 'migrate'))
Well, it is a bit of a chicken-egg problem, you may be able to start your RoR instance without the database created but I doubt it. If your hosting provider is able to host RoR apps, there must be a way for them to run rake for you or to let you run it somehow.
Since it sounds like you are running into troubles with creating the database, is there a way to do it from the hosting control panel? Still, how are you going to migrate your database? Sounds like you might need to look at a new host. I use Slicehost and think they are great :)
Give this code a try:
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
require 'tasks/rails'
Rake::Task["db:version"].invoke
I just tried it in ./script/console and that worked. It wouldn't work without the require lines.
I use it to call other rake tasks from a rake task (when it's not a pre-req but something that has to happen in the middle).
Note, that won't get you any of the output from the command. If you want that you could just go with good old backticks and run the command like this:
output = `rake db:version`
That'll launch another process, but I don't think there's a problem with that.
Just to be clear, you do not need root access, you need just shell (ssh) access to that machine.
How are you deploying it without access ? If you're using capistrano than you already have shell access and it can run those tasks for you.

Resources