Rebuild from migrations

November 27th, 2007

rake db:reset rebuilds from your schema file, which is great, unless you happen to store some data in your migrations, such as creating an admin account for the system. Then you’d like to rebuild from your migrations. To do so, you’d have to rake db:drop, rake db:create and rake db:migrate. Not a big deal, but in early development, sometimes you find yourself changing previous migration files, etc, so you might be doing this more than once – it can get old.

I also like to make sure that my test db is up to date when I recreate the db from migrations and then I like to annotate my models and fixtures (both in rails default test and rspec). Below is a small and simple snip so that you can do just that by typing rake db:rebuild.

I’m personally using an edited version of annotate_models that will also annotate my rspec models and fixtures. I sent this over to Dave Thomas, but I don’t think he has had the time to add it into his plugin. For my use, I just have it sitting on one of my svn servers.

1
2
3
4
namespace :db do
  desc "Drops and recreates the database from your migrations for the current environment and then annotates your models."
  task :rebuild => ["db:drop", "db:create", "db:migrate", "db:test:clone", "annotate_models"]
end

Method Missing

August 15th, 2007

For the last year I’ve been having a love affair with Ruby’s method_missing. Ryan Heneise was the first to show me the power of this method, when working on Moral Metric together. I’m going to show you a very simple example, and perhaps in future snips more complicated uses, of method_missing.

Let’s say we have an application that keeps track of all the super-heroes and villains. We have one table for the super-heroes and villains and a join table for super powers. We want to have clean syntax to return a boolean value for a hero/villain when check if they have a certain power. e.g.

wolverine.has_claws? wolverine.can_heal?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def check_powers(power)
  self.powers.detect { |power| power.name == power } ? true : false
end


def method_missing(method, *args)
  if find = method.to_s.match(/^has_(\w*)\?$/)
    self.check_powers(find[1])
    
  elsif find = method.to_s.match(/^can_(\w*)\?$/)
    self.check_powers(find[1])

  else
    super
  end
end

The first method does our basic check to see if that power exists and returns a boolean value.

method_missing does two matches here. The first checks to see if there is a match for has_something? and the second does a match for can_something? Both take the “something” and send it to our check_powers method to do our detect. Yes, it is that simple, but oh so cool! And, if method_missing doesn’t find what we were looking for, it sends it on up the chain for rails to handle. Neat, huh?

We can get really nice syntax by using method_missing and DRY up our code, quite a bit as well. Definitely a great little nugget to use.

Open Classes

August 14th, 2007

This is really a beginner sample for those who wish that a certain Ruby class had X functionality. Instead of complaining about the lack of something, add it in yourself. Check this out.

I needed to take a Floating point number used as a monetary amount and convert it to “cents” (from dollars) to send for payment processing. I could use the really cool Money Gem, but that was a bit more than I really needed (vendor everything). So, I just opened up the Float class and added my own method:

1
2
3
4
5
class Float
  def to_cents
    self * 100
  end
end

That extends the Float class so that you can do 100.21.to_cents. You can then convert it to an integer if you wanted.

That is how easy it is to extend an existing class with Ruby or Rails – just open it up and add your method(s).

Controller Based Stylesheets

August 14th, 2007

This one is a pretty simple method for organizing and serving specific stylesheets based on what controller your application is currently serving. A friend of mine has written a nice plugin for this, but there is an even easier way to do this:

In your application helper file add:

1
2
3
4
5
6
  def add_stylesheets
    stylesheet = File.join(controller.controller_name, controller.controller_name + ".css")
    if File.exists? File.join(RAILS_ROOT, "public/stylesheets", stylesheet)
      return stylesheet_link_tag(stylesheet, :media => "screen, projection")
    end  
  end

Add to your layout header:


  <%= add_stylesheets %>

I use this in conjunction with:

1
2
3
4
  def body(options={}) 
      options = { :id => controller.controller_name, :class => controller.action_name }.merge(options)   
      tag('body', options, true) 
  end

Patrick’s version goes a bit more granular than my take on it above.

In the example above, I’m assuming you have a directory (public/stylesheets/controller_name/) that is named after your controller which holds the controller specific CSS file. (public/stylesheets/controller_name/controller_name.css) One, this helps organize your CSS in the stylesheets directory and 2) it allows you to separate out your CSS files for easier maintainability and 3) it only loads that controllers CSS file instead of one big file for the whole application (you can of course add more stylesheets for the core of your app in the normal rails way).

Here at work, our CSS files were starting to get rather large and we didn’t need to load those files for every controller – it was just a waste of bandwidth and maintaining them was becoming a headache. Now we just have a couple core “type” files and our controller specific CSS files.

Absence

August 14th, 2007

I’ve been pretty busy lately with working several projects (4 at work and 1 at home) and haven’t had the time to put into this site as much as I would have liked. I do have some plans, in the future, of moving things around and bringing in a buddy of mine to help out with some cool snips on JavaScript. That means this site will be doing some changing – for a future post on my own blog.

Well, I didn’t start this post to just tell you that, I’ve got a few snips here for you to chew on. I’ll break them up in a few separate posts. Here is the first:

1
2
3
4
5
def button_for(name, options={})
  return content_tag(:button, content_tag(:span, content_tag(:span, name)), 
                                        :class => options[:class], 
                                        :type => options[:button_type])
end

The above creates a button element with a couple of span’s within it – not the most semantic, but it does provide a lot of flexibility when styling the button out. You pass the method a name for the inner-inner span element and then a class for the button element with a type (e.g. submit).

This method was originally from my buddy Kevin for one of our projects and I went in a just did a little polishing of the method.

Subversion Directories

June 15th, 2007

Once in a while, I need to remove all .svn directories from a svn repository that I just checkout. So, I go over to Text Drive Snippets and search through the svn code to find the recursive call to do what I need. Well, that is a pain to do each time.

Here’s a quick little bash function that I added to my $HOME/.bash_profile:


rm_svn(){
    find $1 -name .svn -print0 | xargs -0 rm -rf
}

This allows me to recursively remove all .svn directories in whatever directory I pass to it via the command line. e.g. rm_svn . || rm_svn /project

Rcov

May 23rd, 2007

I really like using rcov for my testing. It helps show those little places in your code that could use more tests. However, it gets annoying to keep writing out the rcov test/unit/* rcov test/functional/*. Perhaps there is a better way to run those that is quicker, I’m not sure, but I wrote a little rake task to take care of it for me. Here it is:

1
2
3
4
5
6
7
8
9
namespace :test do
  desc "Run rcov for both unit and functional tests."
  task :rcov => :environment do
    return unless %w[development test staging].include? RAILS_ENV
    `rcov test/unit/*`
    `rcov test/functional/*`
    `open -a firefox #[RAILS_ROOT}/coverage/index.html`
  end
end

That “open -a” line will open up firefox to the index.html page that was just created so you can view your test coverage. It is OSX specific. To for windows, just use start firefox and I assume you can pass the url as I’ve done above, but I’m not quite sure – I haven’t tested it.

Prime Numbers

March 23rd, 2007

This next snip was brought to my attention by Peter Cooper, of Ruby Inside fame. This snip is posted on DZone’s new snippet site, formerly Peter’s snippet site.

1
2
3
4
5
class Fixnum
  def prime?
    ('1' * self) !~ /^1?$|^(11+?)\1+$/
  end
end

The method prime? is being mixed (via open class) in with Fixnum (a Ruby class) to extend it so that simple calls likes the follow now become possible:


 1.prime?

The method will return either true or false, depending if the number is a prime number or not. This is a prime :) example of the power of Ruby’s open class feature. You can add any method to any class that you choose. Also, it demonstrates Ruby’s conciseness – 1 line of code (regular expression!) and you can now call that method on any number.

If you have a favorite piece of Ruby/Rails code or have seen a piece, drop me a line at revans [at] robertrevans ]dot[ com and it may be featured here.

Update As Brian Smith pointed out in the comments, this isn’t a true mixin, as I stated, because the prime is not included with a module that is then include within the Fixnum Class. You see, Module’s don’t have instance methods as classes do, but if you include a Module within a class, those methods within the Module are “mixed in” with the Class that is including the Module.

irb

March 19th, 2007

irb is a great tool to get more familiar with Ruby and test different snips of code. The more I use Ruby the more time I spend in irb testing out small pieces of code or learning more about what the many methods associated with Ruby objects.

Here are two quick tips when using irb. When you want to see what methods are associated with a specific object you can type this into your irb session:

Read the rest of this entry

Here’s a pretty cool article written by Peter Cooper, over at Ruby Inside – a great resource for Ruby/Rails developers alike.

Check it out!

Enter the EigenClass (singleton)

February 24th, 2007

Here’s another snip that is more about best practices, specifically inside the Model of a Rails application.

Often times you may be doing something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  class Ticket < ActiveRecord::Base
  
    def self.find_all_open
      find(:all, :conditions => [ "status = 'open'" ] )
    end

    def self.assigned_to(name)
       find(:all, :conditions => ["assigned_to = '#{name}'"] )
    end

  end

  Ticket.find_all_open
  Ticket.assigned_to("Ryan")
Read the rest of this entry

Body ID's

February 24th, 2007

UPDATE Geoff Grosenbach left a comment of a much more versatile solution than the one used in this post.

Here’s a really quick and simple Rails snip that you can add to your application_helper.rb file.

Say you want to add an id and class to your body element that references the controller and action that you are currently viewing.

1
2
3
  def body_id_class
    "id=\"#{controller.controller_name}\" class=\"#{controller.action_name}\""
  end
Read the rest of this entry

URL-based Breadcrumbs

February 23rd, 2007

Here’s a quick Snip to output URL-based breadcrumbs. Just drop this in your ApplicationHelper:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def breadcrumbs
  r = []
  r << link_to("Home", "/")
  url = request.path.split('?')
  segments = url[0].split('/')
  segments.shift
  segments.each_with_index do |segment, i|
    title = segment.gsub(/-/, ' ').titleize
    r << link_to_unless_current(title, "/" + 
         (0..(i)).collect{|seg| segments[seg]}.join("/"))
  end
  return content_tag("div", r.join(" &#187; "), 
         :class => "breadcrumbs")
end

In your view, put:


<%= breadcrumbs %>

If you’re on the page /articles/my-fancy-schmancy-article

You’ll get a breadcrumb like this:

Home » Forum » My Fancy Schmancy Article

Inspiration from joshhuckabee.com/node/58

Splatter that Array

February 23rd, 2007

This something fairly new to me, although I’ve seen it used by Ruby Guru’s – the splat operator *.

From my understanding, the splat operator takes an array and pulls the contents out of the array. It takes one argument and then takes that array and pulls the contents out. It’s still a bit confusing to me on some aspects, but here are a few examples to help simplify it:

Read the rest of this entry

Add to Array if...

February 22nd, 2007

Here is a real quick Ruby Idiom that is quite helpful.

Let’s say you have a shopping list that you have declared as an array and you want to add an item to your list. You’d first want to make sure that it isn’t on your list already. You don’t want to buy two or more jars of peanut butter!

1
2
  shopping_list = ['peanut butter', 'grape jelly', 'whole wheat bread']
  shopping_list |= ['peanut butter']

The first thing I did was create the array for my peanut butter and jelly sandwhich and then I proceeded to add peanut butter to my list, if it isn’t already on my list. Since it is, it was not added to my shopping list array.

Gotta love Ruby Idioms!