Archive for the 'Ruby on Rails' Category

19
Jul
09

Mock Cookies in Rails Tests the Easy Way

I got really tired of mocking out cookies every single time I made a reference to cookies in my test. It looked like a bunch of spaghetti code that made me mock out every single cookie call that I could imagine. Don’t get me wrong, I think mocks are wonderful, but when you have to mock out every single call, I don’t think the pain is worth the gain. I found it much easier to mock cookies like this as like this, which gives a pretty good approximation of rails cookies. It won’t work for 100% of cookie testing cases, but for 99.9%, it works like a charm.

I use rspec to test, but you could easily port the Cookie class to any testing framework that you want.

def stub_cookies
  stub!(:cookies).and_return(MockCookie.new)
end

class MockCookie < Hash

  def [](name)
    super(name.to_s)
  end
 
  def []=(key, options)
    if options.is_a?(Hash)
      options.symbolize_keys!
    else
      options = { :value => options }
    end
    super(key.to_s, options[:value])
   end

  def delete(key,opts)
    super(key)
  end

end

08
Jul
09

DRY Views in Rails with Blocks

I’m a fan of the DRY (Don’t Repeat Yourself) principal. I think that computers were invented for a reason and that reason was not so that I could do the same thing over and over. If it’s one thing that computers do well, it’s doing the exact same thing ad nauseum. So, I do as much as I can in order not to repeat myself a lot when coding.

I have an case now where within the main portion where content is rendered sometimes there separate content on the right side, and sometimes there is not. For example, with no content on the right side, it looks like so:

  <div id="left">
    I am left content
  </div>

Simple enough, but when there is content on the right side, the left side has to get a little smaller, so there is a class added called “with_left” to the left div that makes the width less to accommodate the right content.

  <div id="right">
    I am right content
  </div>
  <div id="left" class="with_right">
    I am left content
  </div>

The problem comes in when the right content is different from page to page and I’m not exactly sure if there is going to be any right content to begin with, as it relies on some dynamic data. Sure, I could do something like this for every page, but I would get annoying fast, and I’m sure there would be one instance where I would forget to do it the right way:

  <% if right_content %>
    <div id="right">
      <%= right_content %>
    </div>
  <% end %>
  <div id="left" <%= 'class="with_right"' if right_content -%>>
    I am left content
  </div>

So, in comes Ruby to the rescue. I heart blocks and I’m glad that ruby has them, because this is a great case where they come in handy. Instead of doing the above logic over and over again, I can create a method called main_content that allows me to do this in a more generic way.

  def main_content(params={},&amp;block)
    right_content = params[:right_content]
    unless right_content.blank?
      right_div = <<-HTML
        <div id="right">
          #{right_content}
        </div>
      HTML
      concat(right_div)
      concat('<div id="left" class="with_right">')
    else
      concat('<div id="left">')
    end
    yield
    concat('</div>')
  end

Now I can use this method like so:


  <% main_content(:right_content=>render(:partial=>'account_actions')) do %>
    <h3>Edit Account</h3>
  <% end >%

If the partial account_actions renders anything, I will get this:

  <div id="right">
    Output of account_actions partial
  </div>
  <div id="left" class="with_right">
    <h3>Edit Account</h3>
  </div>

If the account_actions partial doesn’t end up rendering anything, then I get:

  <div>
    <h3>Edit Account</h3>
  </div>

Nice! Everything looks good, so I can start adding some tests to it. Here’s how I tested it with rspec:

  describe 'main content renderer' do
    
    before do
      @buffer = ""
      stub!(:output_buffer).and_return(@buffer)
    end
    
    it 'will render only the left div when there is no right content' do
      main_content{}
      output_buffer.should have_tag("div#left")
    end
    
    it 'will put the yielded content in the left div' do
      main_content{concat("Yielded content")}
      output_buffer.should have_tag("div#left","Yielded content")
    end
    
    it 'will display the right content in the right div if there is any' do
      main_content(:right_content=&gt;'Right'){}
      output_buffer.should have_tag("div#right","Right")
    end
    
    it 'will add a class of "with_right" to the left div if there is right content' do
      main_content(:right_content=&gt;'Right'){}
      output_buffer.should have_tag("div#left.with_right")
    end
    
  end

17
Jun
09

Super Easy Tabs in Rails

All the cool kids these days seem to be doing navigation via tabs, and since I want to be cool, too, I figured I might as well do it to. Ya, sure, there are plenty of plugins out there that do this, but it always seems like these things have too much configuration and code for its own good.

So, I went at it on my own and, really, if the tabs are simple, the solution is pretty simple. My tabs are based on the controller name, which means the current tab maps to all the actions of a certain controller. In other words, it’s kind of the way Basecamp does it.

First, let’s start with some code in the controller. In my app, everything that uses tabs is inherited from a base controller called LoginProtectedController. That’s where I put this code, but it would work just as well in the ApplicationController:

  helper_method :current_tab

  def self.current_tab(tab_name)
    before_filter do |controller|
      controller.send(:current_tab=,tab_name)
    end
  end

  protected

  def current_tab=(tab_name)
    @current_tab = tab_name
  end

  def current_tab
    @current_tab || controller_name.titleize
  end

So, this is what I have in one of my controllers to mark that the tab is not the name of the controller, but called ‘Dashboard’

  current_tab 'Dashboard'

Now for some helper code for displaying the tabs:

  def tab_link(args={})
    html_options = {}
    html_options = {:class=>'current'} if args[:tab] == current_tab
    link_to args[:tab], args[:path], html_options
  end

And here’s how you put it together in the view:

<div id="navigation">
  <%= tab_link("Dashboard", :path=>admin_path) %>
  <%= tab_link("Items", :path=>admin_items_path) %>
  <%= tab_link("Users", :path=>admin_users_path) %>
  <%= tab_link("Account", :path=>edit_admin_account_path) %>
</div>

If you want to make it look all pretty, some CSS should spruce it up:

#navigation {
  line-height: 100%;
  margin-left: 6px;
  float: left;
  font-size: 12px;
}

#navigation a {
  background-color: #CCCCCC;
  color: #000000;
  padding: 7px 15px;
  text-decoration: none;
  display: block;
  float: left;
  margin-left: 2px;
}

#navigation a:hover {
  background-color: #BBBBBB;
}

#navigation a.current, #navigation a.current:hover {
  background-color: #FFFFFF;
}

30
Apr
09

Time for Rails to Grow Up

So, I’ve been particularly absent in my internet time as I’ve moved from Argentina, then the States, then Korea all in the past 3 months. In other words, it’s been a bit hectic lately.

And what do I see when I come back? It’s an argument over a presentation that someone did at the Golden Gate Ruby Conference called “CouchDB: Perform like a pr0n star”. You can see the slides at the end of this blog.  There has been much debate on it, as seen here, here, and here (and probably at many other sites, too).  During the whole thing some people say “so what” while others say it’s a disgrace while DHH and many of the core developers as I understand it have actually embraced it, theorizing that edgy is good.  This actually casued one of the ruby activists,




Stay Updated

or

Get new posts via email

Software Blogs - BlogCatalog Blog Directory

 

May 2012
M T W T F S S
« Jul    
 123456
78910111213
14151617181920
21222324252627
28293031  

Follow

Get every new post delivered to your Inbox.