The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Rails Model View Controller + Presenter?

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Jay Fields

Posts: 765
Nickname: jayfields
Registered: Sep, 2006

Jay Fields is a software developer for ThoughtWorks
Rails Model View Controller + Presenter? Posted: Sep 30, 2006 2:43 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Jay Fields.
Original Post: Rails Model View Controller + Presenter?
Feed Title: Jay Fields Thoughts
Feed URL: http://blog.jayfields.com/rss.xml
Feed Description: Thoughts on Software Development
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Jay Fields
Latest Posts From Jay Fields Thoughts

Advertisement
Ruby on Rails directs you to use Model View Controller by convention. This often results in a one to many relationship between Controllers and Views. A common controller could contain the following code.
class StandardsController < ApplicationController

def list
@standards = Standard.find(:all)
end

def results
standards = Standard.find(:all)
@total_standards = standards.size
@standards_for_hr = standards.select { |standard| standard.department == 'hr }
@standard_catagories = standards.collect { |standard| standard.catagory }.uniq
...
end

end
This controller implementation works fine; however, the results method can become a bear to test. To solve this issue my team began inserting another layer: a Presenter. The main responsibility of a Presenter is to expose data for the view to consume. After introducing the presenter the controller becomes much slimmer.
class StandardsController < ApplicationController

def list
@standards = Standard.find(:all)
end

def results
@presenter = Standard::ResultsPresenter.new()
end

end
The Standard::ResultsPresenter class handles aggregating all the required data.
class Standard::ResultsPresenter

def total_standards
standards.size
end

def standards_for_hr
standards.select { |standard| standard.department == 'hr }
end

def standard_catagories
standards.collect { |standard| standard.catagory }.uniq
end

def standards
Standard.find(:all)
end

end
After introducing this abstraction the Presenter can be tested in isolation.
class Standard::ResultsPresenterTest < Test::Unit::TestCase

def test_total_standards
Standard.expects(:find).with(:all).returns([1,2,3])
assert_equal 3, Standard::ResultsPresenter.total_standards
end

def test_standards_for_hr
standard_stubs = [stub(:department=>'hr'), stub(:department=>'other')]
Standard.expects(:find).with(:all).returns(standard_stubs)
assert_equal 1, Standard::ResultsPresenter.standards_for_hr.size
end

def test_standard_catagories
standard_stubs = [stub(:catagory=>'Ruby'), stub(:catagor=>'Ruby')]
Standard.expects(:find).with(:all).returns(standard_stubs)
assert_equal ['Ruby'], Standard::ResultsPresenter.standard_catagories
end

end
We like this style because it's much cleaner than the previously required code that lived in the controller tests. However, there is overhead involved in generating this additional layer. Because of the overhead we generally don't add a presenter until we notice that testing has become painful in the controller test file.

Read: Rails Model View Controller + Presenter?

Topic: Deploying to Staging and Production with Capistrano Previous Topic   Next Topic Topic: Popular RubyForge themes

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use