assert_select the order of a drop-down in Ruby on Rails

Posted on January 14, 2008

To write a functional test to determine the correct order of a dropdown do the following:

    option = css_select("select#id_of_dropdown option")[n]
    assert_equal "Value To Compare", option['value'].to_s

And replace id_of_dropdown with the dom id for the drop down you’re looking for, replace n with the nth number, and replace ‘Value To Compare’ with the value you’re looking for.

So for example, if you have a dropdown with an id of ‘fruit’ and you want to make sure that the third option is ‘banana’ use this:
    option = css_select("select#fruit")[3]
    assert_equal "banana", option['value'].to_s

Ruby on Rails: Grabbing the model object using the controller name

Posted on January 09, 2008

I found myself in a situation where I was creating basically the same method in many of my controllers, the only difference being the name of the model object. For example:

class ArticlesController

 # .... cut 

 def set_recommended(is_recommended)
    @article.recommended = is_recommended
    @article.save    
    respond_to do |format|
      format.js { render :nothing => true }
    end    
 end

class MoviesController
 # .... cut 

 def set_recommended(is_recommended)
    @movie.recommended = is_recommended
    @movie.save    
    respond_to do |format|
      format.js { render :nothing => true }
    end    
 end

end

So, I want to refactor this code, and create one method for this in the application.rb file – but how to refer to the @movie and @article objects?

Simply by using the instance_variable_get method! You simply pass in a string with the name of the method, and it returns the instance variable.

Here’s how the new method looked within the application.rb file.
class ApplicationController
 # .... cut 

  def set_recommended(is_recommended)
    object = instance_variable_get("@#{self.controller_class_name.chomp("Controller").singularize.underscore}")
    object.recommended = is_recommended
    object.save    
    respond_to do |format|
      format.js { render :nothing => true }
    end        
  end

end

Of course, this only works for controllers and model names that follow the singular, plural convention (i.e. model name is article and controller name is ArticlesController)

Default columns in fixtures

Posted on January 03, 2008

Ever find yourself writing out the same old column names in fixtures just so your tests will work? Ever wonder if there’s a better way? Well there is!

Fixtures, now with NEW default columns!

All you need to do is bung a method in your test/test_helper.rb file that looks like this:

  def default_columns
    columns = <<END_OF_STRING
    created_at: 1 Jan 2007
    created_by: 1
    updated_at: 1 Jan 2007
    updated_by: 1
    lock_version: 1
  END_OF_STRING     
  end

Now, in each fixture that requires the default columns put this at the top:

<% require "#{RAILS_ROOT}/test/test_helper.rb" %>                    
And then for each fixture bung in this inline code:
one:
  id: 1   
  name: MyString
<%= default_columns %> 

Voila! No more repeating yourself with stupid columns! Hooray!

Note: spacing is important in yaml files – so make sure you put the <%= default_columns %> in an appropriate place