Although Rails improves development speed by its excellence and design, there are a bunch of tricks you can use to improve even further. This page documents these: Please add any time savers you happen to come up with! See Gotcha for solutions to some unexpected effects of Rails.
Add a new file in /lib/rake I called mine “app_management.rake”.
Put the following command in the file and save it. You will now see whatever you put in for the rake task name as well as the description if you run “rake -T” at your app root at the command line.
namespace :db do
desc "create default admin user"
task :create_admin => :environment do
admin = User.create(
:login => "admin",
:name => "Admin",
:email => "email @ address . com",
:password => "Password01",
:password_confirmation => "Password01"
)
admin.activated_at = 5.days.ago
admin.activation_code = nil
admin.save false
end
end
Invoke the command with the following (again at the command line in the root of your app: “rake db:create_admin”
Here is a little snippet I use for quickly testing edge, normal and error data points against my model validation.
Create/Edit the .irbrc file in your home directory (UNIX users) and add the following code:
IRB.conf[:AUTO_INDENT] = true
IRB.conf[:USE_READLINE] = true
IRB.conf[:LOAD_MODULES] = [] unless IRB.conf.key?(:LOAD_MODULES)
unless IRB.conf[:LOAD_MODULES].include?('irb/completion')
IRB.conf[:LOAD_MODULES] << 'irb/completion'
end
Now, when you are typing commands into IRB, you can hit the “tab” key and it will automatically complete the command for you or display a list of possible commands if the prefix is ambiguous.
A bunch of errors occur because of bad template code. Although you can debug these by switching between your browser and IDE, it’s easier if you can view the problems in your IDE.
An quick way to do this is to add this script to your path:
<pre>
#!/bin/sh
/usr/bin/erb -x $1 | ruby -c
</pre>
Configuring your IDE to run this script is highly dependent on which IDE you use. It should be pretty easy however, and any editor worth its bits should support running it with a quick key combo.
If a URL doesn’t match any of your routing rules, you may see a diagnostic page saying “RoutingError: No route for path: asdf”. This can be very helpful when developing your application, but looks ugly if your users see it.
Happily, in production mode, Rails responds to routing errors by rendering /404.html instead. So, just change config/environment.rb when you go live, and edit your 404.html file to match your application.
See also HowtoConfigureTheErrorPageForYourRailsApp
Deleting all sessions
When upgrading to 0.11, you need to delete your sessions. Sometimes, if your web server ungracefully exits, you might need to clear the sessions too.
/tmp/ruby_sess*.%TEMP%\ruby_sess*, where TEMP is the environment variable of that name.Deleting Old Sessions
The following will delete sessions which are over 60 minutes old.
<pre>find /tmp/ -name "ruby_sess*" -cmin +60 -exec rm {} ;</pre>
I needed to escape the semicolon for it to work :
<pre>find /tmp/ -name "ruby_sess*" -cmin +60 -exec rm {} \;</pre>
And then I put that in an hourly-run cron script.
Note on Rails 1.1: Session files are now stored by default within each app’s own directory structure. Look for “tmp” in your app.
this is my experience with WEBrick,
if you are having problems with rails not finding routes.rb after you refresh more than once, and get this error message,
Cannot load config/routes.rb: No such file to load — ./../config/../config/routes.rb
then you are probaly starting WEBrick from the script directory directly,
WEBrick should be started from your root rails app, as script/server
You can also use script/runner if you like — Ulysses
What this does is use the controller action that you specify as your homepage as opposed to the index.html file in the public folder
First thing is to remove the index.html file in the public/ folder.
Then go to config/routes.rb and insert this as the first entry:
<pre>
map.connect "",
:controller =>"controller_name",
:action => "method_name"
</pre>
If you have a table with just one entry, useful for keeping track of a number sequence for databases without sequences, you can use the singleton module included with ruby like so:
<pre>
require 'singleton'
class Master < ActiveRecord::Base
include Singleton
end
When you make a rails project, the dispatch files in the public directory will have an absolute path to ruby on your development machine in its “hashbang” line, for example
<pre>
#!/opt/local/bin/ruby
</pre>
(The astute reader will know what kind of computer I use:-)
When you deploy it, this line must be the path to ruby on the server, for example
<pre>
#!/usr/bin/ruby
</pre>
Some people make soft links where they need to, and edit the original dispatch files placed in the public directory by rails. I wanted to have Capistrano edit them for me, automatically. So I wrote a script…
<pre>
#!/usr/bin/env ruby
current_path = ARGV[0]
new_hashbang = ARGV[1]
f_names = %w(dispatch.cgi dispatch.rb dispatch.fcgi)
f_names.each do |name|
puts `ls -al "#{current_path}/public/#{name}" `
File.open("#{current_path}/public/#{name}", "r+") do |f|
f_contents = f.read
f_contents.gsub!(/^#!.+$/, new_hashbang)
f.rewind
f.write(f_contents)
end
end
</pre>
…and put it in the script directory as fix_hashbangs.rb. Then I added a few lines to Capistrano’s deploy.rb in the config directory:
<pre>
set :server_hashbang, '#!/path/to/server/ruby'
desc “Edit hashbang lines in public/dispatch.*”
task :before_restart do
run “#{current_path}/script/fix_hashbangs.rb #{current_path} ‘#{server_hashbang}’”
end
And that’s it. Now Capistrano automatically edits the dispatch hashbang lines before it restarts the fcgi processes.
I’ve been making use of migrations a bit and found the lack of fixtures in Development mode a bit of a pain. (I’m sure there’s a better way of doing this but I haven;t found it yet.)
I quickly twigged that migrations can add records by simply doing:
<pre>
Person.create :firstname => 'Jeremy', :sirname => 'Garside'
</pre>
But when I wanted to work using Single Table Inheritance then setting the :type was a no-no:
<pre>
Person.create :firstname => 'Jeremy', :sirname => 'Garside', :type => 'Player'
</pre>
I tried various approaches to syntax including .class but clearly don’t know enough Ruby…
What did work for me is the following:
<pre>
class CreatePeople < ActiveRecord::Migration
# This approach lets you add the :type, which can't to be set elsewhere...
# Not sure of it has any implications elsewhere, mind. [:type] didn't work for me.
end
I’d welcome correction if there is a better approach to this!
Jeremy Garside
This is described in Agile Web Development with Rails, so I can’t claim any credit. Before we start, I should also point out that the above method can be faster and easier if you only need to add one or two records to the database. Keep in mind that this will load data in both production and development environments, so you may wish to load fixture data manually if you only want the data for development.
It is a good idea to create a new directory for your fixtures to live in. The book suggests db/migrate/dev_data, but it can be anywhere you want. Things do go more smoothly if you choose to place your fixtures in a subdirectory of db/migrate.
Next create your fixtures as yaml files; the format is described in ActiveRecordYamlFixtures
In your migration, include code similar to the following:
require 'active_record/fixtures' directory = File.join(File.dirname(__FILE__), "dev_data") Fixtures.create_fixtures(directory, "users")
In the above example, ActiveRecord will look for a file named “users.yml” in db/migrate/dev_data/ and load the data in the database. Change the directory and fixture name to suit your needs.
If you’re a clean freak like I am, you can use this snippet to alphabetize your migrations if you generated your models in a non-alphabetical order.
This assumes you have only create migrations.
rails/db/migrate $ ls | perl -n -e 'chomp; push @a => [$_, (/create_([\w_]+).rb/)[0]]; END{ system sprintf "svn mv $_->[0] %03i_create_$_->[1].rb\n", ++$j for sort {$a->[1] cmp $b->[1]} @a }'
If you are connected to a busy development SQL server or find it hard to read through your system’s SQL logs for any reason, it’s possible to create direct logging of only your Rails application’s commands. Here’s an article on how to accomplish that:
When you need to add a column to an existing table, if you following the convention of naming your migration Add
Rails Migrations – Command Line Power in 2.0
Works fine, just as long as you don’t name your partial _flash
There’s a growing trend to abuse before_filter in controllers to load data for multiple actions. This is not what before_filter is for, and using it this way makes code harder to read and maintain as well as negating the benefits of controller action caching (and possibly other current or future Rails features).
As a rule, use before_filter only for actual filtering, and always use before_filter for code that does do filtering. When you want to factor out common initialization code, simply call the shared initialization method at the start of each action method that needs it.
Note I have moved this to the bottom of the page because it breaks the formatting of all that follows it. If it can’t be fixed, it would be ideal if we had a link to the resource instead of all the funky tags.
I’ve found this code immensely helpful whil developing my site. Good for quickly checking the contents of your session and passes parameters. I put this in the footer of my layout:
<pre>
<%= javascript_include_tag 'prototype' %>
<% if ENV['RAILS_ENV'] == 'development' %>
<div id="debug" style="margin: 40px 5px 5px 5px;">
<a href="#" onclick="Element.toggle('debug_info');return false" style="text-decoration: none; color: #ccc;">Show Debug Info ➲</a>
<div id="debug_info" style="display : none;">
<%= debug session %>
<%= debug params %>
<% end %>
Also take a look at the Textmate Footnotes Plugin if you’re developing with Textmate (or the clon http://antono.info/en/3 for Vim or other editors).
Also interesting is the debug_view_helper plugin found at http://www.realityforge.org/articles/2006/03/20/rails-plugin-to-help-debug-views
—
I made some modifications to the code above to make it print a “prettier” version of the session store and the params:
<% if ENV['RAILS_ENV'] == 'development' %>
<div id="debug" style="margin: 40px 5px 5px 5px;">
<a href="#" onclick="Element.toggle('debug_info');return false" style="text-decoration: none; color: #ccc;">Show Debug Info ➲</a>
<div id="debug_info" style="display : none; white-space:pre;">
SESSION:
<%= session.pretty_inspect %>
PARAMS:
<%= params.pretty_inspect %>
</div>
</div>
<% end %>
Notice that it’s necessary to include pp.rb. I took care of that by requiring it in environment.rb