Sohan's Blog

Things I'm Learning

Rails Modeling Guide#2: Naming Convention for Ruby on Rails Model Methods

Naming conventions play an important role to the software’s overall architecture. It is not a rocket science, still, it may lead to unhappy consequences if not taken care of at the early stage of a project. This small best practices can make a code base significantly improved.

Rails does a good job by using the dynamic power of ruby and providing with a handful of dynamic methods with the models. ActiveRecord::Base and its included modules follow a consistent naming, which clearly represent the intended purpose of the methods. At Code71, we are working on ScrumPad, a 2nd generation agile scrum tool using ruby on rails and our model methods are named according to the following rules-

1. All boolean returning methods end with ‘?’

company.billable?, sprint.current?, story.in_progress?

2. Boolean methods do not start with is_ or has_ or did_ (as you might see in other popular languages)

company.is_billable? -> company.billable?
sprint.is_current? -> sprint.current?

3. find_ and find_all are used only for class (self.find or self.find_all) methods and should return a single/array of object of the class respectively.

find_* methods may return a single object of the class/nil

find_all_* methods return an array of objects of the class or [], but never a nil

4. No methods start with a get_ as other languages.

5. A method ends with ! if it alters the object itself.

sprint.close!()
story.progress!()

6. Methods that persists an object/may throw exception, should always end with ! (implied from rule 5)

invoice.update_status!(:paid)

7. Always use parentheses ‘()’ in method names. Future versions of ruby is deprecating the support for method names without parentheses.

Following these 7 simple rules we have consistent and intuitive model method names across the whole ScrumPad. Let me know if you have any suggestion to these names to make it even better.

Comments

Sohan
@Ashif, thanks!
Ashif Manjur
Thanks for these great tips. Sometimes only following the naming convention can save us a lot of time and effort to understand codes written by others. Keep posting such tips and tricks of beautiful coding.

Rails Modeling Guide#1: Right Structure of a Ruby on Rails Model

30MAR4U

Rails models are no exception compared to the super models! You are in the business if and only if you got a good physical structure and can stick to it for years…

At Code71, we are keeping our rails models attractive following a few guidelines. I will be posting these guidelines in a series and here goes the first one - about the physical structure of the ruby on rails models.

We keep the following order consistent in our models:-

  1. CONSTANTS
  2. has_one, has_many, belongs_to, has_and_belongs_to relations in dependency order
  3. plug-ins initialization (acts_as_tree, acts_as_state_machine etc.)
  4. validates_presence_of
  5. validates_uniqueness_of
  6. validates_numericality_of
  7. validates_format_of
  8. custom_validations
  9. named_scopes grouped by related purposes
  10. active record hooks (after_initialize, before_create, after_create, …) in execution order in the format (after_initialize [:assign_default_state, :sanitize_content] )
  11. protected
  12. hook method implementations according to execution order
  13. public
  14. constructor
  15. class methods in alphabetic order
  16. other methods alphabetically or grouped if related
  17. protected
  18. methods alphabetically or grouped if related
  19. private
  20. self methods in alphabetic order or similar methods in a group
    other methods in alphabetic order or similar methods in a group

Rule

No method gets code real estate over 20 lines. If needed, one/more private methods are used.

How is this helping us?

  1. We are absolutely sure where to look for a method or where to write a new method.
  2. The code base is really consistent.
  3. The unit test methods also follow the same order, which makes managing the test suite easy.

More to come later this week. Stay tuned!

Implementing Breadcrumb in Rails Projects – a Clean Approach

breadcrumb

In most web applications, breadcrumbs offer a nice way to trace back to previously visited pages. However, generating the breadcrumbs and showing them on dynamic pages sometimes need special care for the following reasons-

  1. The links of the breadcrumb may contain dynamic links.
  2. It is used in all the pages. So, changing the breadcrumb may trigger a series of changes.

In ScrumPad, we are using ruby on rails. There are a few plugins to help rails projects in managing breadcrumbs, but none seemed to satisfy our need. In fact, most projects come up with some distinctive ways to generate the breadcrumbs. However, we kept the breadcrumb clean in the following way in ScrumPad.

Step#1:

Encapsulated the breadcrumb generation logic into a single class and used it from all places.

class Breadcrumb
include ActionView::Helpers::UrlHelper
include ActionView::Helpers::TagHelper
include ApplicationHelper

attr_accessor :parts, :separator, :prefix

def initialize(separator = nil, parts = [])
self.separator = separator || "<img src="\"/images/stub_arrow_right.gif\"" />"
self.parts = parts
end

def add(title, url = nil)
self.parts << {:title => title, :url => url}
end

def set_prefix(title, url)
self.prefix = {:title => title, :url => url}
end

def to_s
if(!self.parts.nil? and !self.parts.empty?)
if(self.prefix.nil?)
parts_with_prefix = self.parts
else
parts_with_prefix = [self.prefix] + self.parts
end

breadcrumb_html = []
parts_with_prefix.each do |part|
if(part[:url].nil? or part[:url].empty?)
breadcrumb_html << "#{part[:title]}"
else
breadcrumb_html << link_to(part[:title], part[:url])
end
end
return breadcrumb_html.join(" #{self.separator} ")
end
return ''
end
end

Step#2:

A before_filter in the ActionController initializes the breadcrumb in the following way:-

def initialize_breadcrumb()
@breadcrumb = Breadcrumb.new
if(project_selected?)
@breadcrumb.prefix = {:title => "Dashboard", :url => dashboard_project_path(selected_project())}
end
end

Step#3:

Now, @breadcrumb is available to all actions. However, if the RESTful resource definition is right, the rest of the breadcrumb generation becomes really simple. We have methods like the following in our controllers-

def generate_breadcrumb(sprint, story = nil)
@breadcrumb.add(sprint.name, project_sprint_path(project.id, sprint.id))
if(!story.nil?)
@breadcrumb.add(story.display_title, story_path(story))
elsif(self.action_name != 'index')
@breadcrumb.add('Stories', stories_path())
end

current_page = self.action_name == 'index' ? 'Stories' : self.action_name.humanize
@breadcrumb.add(current_page)
end

Step#4:

Finally, in my view layout, I just use this instance variable as shown here:-

<%= @breadcrumb %>

So, the whole breadcrumb generation is encapsulated and the implementation is clean. Let me know if you liked it. I am in the process of creating a plugin so that anyone can just drop it in any rails app and start using straight away!

Comments

Jesse Cai (蔡望勤)
very cool, will be a nice plugin.
Samiron Paul
This was really a cool way to implement breadcrumb in Rails. Looking forward for the plugin… as it really seems lifesaver for developers :)

Lesson#2: Pace Your Sprint Rightly

In my previous post, I said about being incremental. Here come the next thing, being “ITERATIVE”. A prefer the term Sprint than Iteration.

So, once you decided to take small increments, make sure you reach the targets sprinting.

sprint

I suggest you prepare for sprinting with the right techniques and tools. A few recommendations-

  1. Never miss a daily standup meeting. Spend only 2 minutes (or less) per person answering the three questions – what did you do yesterday, what’s on the plate for today and what is blocking the race?
  2. Install visual clues for bringing the under the hood stuffs to daylight. Remember, being able to address the loopholes is the key. The solution usually follows automatically.

The key concept to internalize is, sprinting is a balance race. You need a good start and keep the momentum to reach the touch line on time. Its a small race and if you fall back, the touch line may seem too far to celebrate.

At Code71, ScrumPad, is helping us in sprinting. Our sprints are two week sprints in most projects. We found the team communication holds a key in meeting the deadline. Since, within a sprint, someone of the team may need an unplanned vacation or an issue may arise out of the blue, the team needs to step up and put extra efforts. Again, visual clues help the team in keeping everybody posted timely.

If a team finds it difficult to meet the deadline and find the sprint length to be too small, then what? Should they linger the sprint length? NO. The solution is to even shorten the length. To make sure, the team can plan for short spans with better accuracy. Lingering the sprint length addresses the wrong disease and hence may not solve the problem.

Comments

Ashrafuzzaman
I think 2 week sprint is a good sprint length and appropriate for most of the project.
Ashrafuzzaman
I think, two week sprint is a good sprint length and is appropriate for most of the projects.
Tanvir Anowar
I think for big projects and a big teams sprint lengths also should have to be big enough for a maximum outcome.

Lesson#1: Going Incremental Is Natural!

As Scrum and Agile processes tell you, do it in small sprints, 2 weeks preferably, and go incremental. Take a small piece at a time and sprint.

human-evolution-t10176

I took this image from internet and credits to this site.

It’s easy to work out the Natural way than to defy it! If you are iterative and incremental, you are reaching towards the right hand side of the image! And to make the evolution faster, I suggest you try out Scrumming with ScrumPad. If you value “teaming” and “delivering” in sprints, ScrumPad will give you the oxygen to breathe while you sprint!

I suggest you follow a routine to iterate. At Code71, we follow the below-

Day 1: Plan for the next 9 days. Breakdown work items into smaller tasks, estimate at hours for each of the tasks and assign each task to an individual.

Day 8: Release in test server (shadow version of the real production environment) and collect customer feedback.

Day 9: Work on customer feedback and go live in production server. Always tag the version that is put in the production following the standard -

R<ProductReleaseVersion>.S<SprintNumber>.B<BuildNumber>.P<PatchNumber>

This gives us the rollback point when there is any issue in the latest production deploy. Of course, we make sure we do not need to touch on the tags too often!

How are you sprinting? Let me know if you have a suggestion.

Comments

titu
Very helpful post for the beginner who want to learn about Scrum. In Code71 we are using ScrumPad from it's 2nd sprint. It helps us to speed up our project work as well as follow the Scrum. Also collaboration part is very helpful to communicate with clients specially for the team who work remotely.
Tanvir
Good post.I think incremental development process plays a pivotal role over waterfall in software industry(for most of our regular projects) nowadays.

Its Easier to Get Lost! Would You?

I was talking to a friend of mine, who started a IT start up and working full time with a few others to foster the business. He was telling me-

“We have 13 projects running at this moment. We are working our heart out. But, we are not finding any time to do Test Driven Development, Continuous Integration and all the good things…”

Well, I understand how it feels! As the title says, “Its easier to get lost!”

maze 

Do you fancy getting stuck at this maze?

For startups, it is difficult to control the pulse. Because, you want to reach your billion dollar spot as early as possible, this week, or even earlier, today or even just in a few hours! And, as days go by, you start to feel the need for some process, to safeguard your efforts and quality, to hit the deadlines, to get in the rhythm of a sustainable pace.

But it may be really difficult to catch the ball at the first jump. We, at Code71, believe we need to be visibly competent and confident about the quality of our work. And worked hard to get the gears together in motion. Now it is cliques great. We have got the people motivated to follow the best practices, the tools to “do more with less” and the process to ensure a “sustainable pace”. I advise, you do at least the following to learn to escape the maze from tomorrow-

    • DIE for planning. Plan for short spans. We plan for two week sprints.
    • While planning, estimate honestly. Estimate all the hours necessary for following best practices. (producing automated test scripts may take 40% longer time, but bear with it)
    • Plan on your inputs. You cannot push your inputs. So, you may need to squeeze the output to match against your capacity.
    • DIE to meet the deadline according to the plan.

This is the mindset. You need to start believing to sustain. You need to plan honestly and never miss a deadline. After reaching the deadline, you retrospect. Find the loopholes and start filling those one by one. If you don’t see a loophole, find a ladder to reach higher. But do not place a ladder on a land mine!

Its not difficult if you have the preparation. To prepare, at a minimum do the following-

  • Have a Continuous Integration (CI) server up and running 24x7 or DIE. (We use CruiseControl, its free and great)
  • Make your CI server to send build, test and coverage report for you. Keep an eye on the coverage report and DIE to remain well above the the 80% line.
  • Keep track of your activities for retrospect. We use ScrumPad. It helps you to iterate, collaborate and deliver.

The keyword is “sustainable pace”. I found Scrum to address this sustainable pace really smartly. If you haven’t tried yet and looking for the loopholes to fill or the ladder to climb up, I suggest you learn about agile and Scrum, find an expert and give it a try. It’s worth than you might have expected.

If you know a better way to keep delivering better, I will appreciate for sharing your idea to me.

Comments

Sohan
hmm… let me know if I can be of any help :-)
R O M E L
my 1st comment was just a casual comment(please take it frienly comment)… please don't take it seriously… we tried to study about scrum and follow the principles many times but could not persist…
R O M E L
we thought of scrum so many times and couldn't organize ourselves… :(

Unit/Functional Test Rails ActionController Filters Following DRY

At ScrumPad most of our controllers are bounded by filters for authentication/authorization. Some filters apply to all actions in a controller while others apply to only a few or leave out only a few. However, since we are following TDD, we need to test the filter is invoked before each of the desired action. This makes the test code MOIST (not DRY)!

Example of Moist Code:

The following example only captures two test methods. However, if you have 30 controllers like ours and on an average 5 filters at each, you will possibly find many such duplicates making your test code so moist that it becomes shabby!

class SomeController
before_filter :authenticate
before_filter :restrict_invalid_role
end
class SomeControllerTest
def test_index_redirects_without_login
get :index
assert_redirected_to :controller=>:login, :action=>:login
end
def test_index_redirects_without_valid_role
login_as(:invalid_role)
get :index
assert_redirected_to :controller=>:exception, :action=>:not_allowed
end
end

Example of DRY Code:
I came up with the following implementation to help us with unit testing the before filters. The assumption is, if your filter is invoked, it will work fine. And we are testing the filter only once. The following code is written at the end of the test/test_helper.rb.
class ActionController::TestCase
##example: should_apply_before_filter_to_actions(:authenticate, [:index, :new])
def should_apply_before_filter_to_actions(before_filter_name, actions)
if(actions.nil? or actions.empty?)
assert false
end
filter = find_maching_before_filter(before_filter_name)
actions.each do |action|
assert_before_filter_applied(filter, action)
end
end
##example: should_apply_before_filter_to_action(:authenticate, :index)
def should_apply_before_filter_to_action(before_filter_name, action)
filter = find_maching_before_filter(before_filter_name)
assert_before_filter_applied(filter, action)
end

##example: should_not_apply_before_filter_to_actions(:authenticate, [:index, :new])
def should_not_apply_before_filter_to_actions(before_filter_name, actions)
if(actions.nil? or actions.empty?)
assert false
end
filter = find_maching_before_filter(before_filter_name)
actions.each do |action|
assert_before_filter_not_applied(filter, action)
end
end

##example: should_not_apply_before_filter_to_action(:authenticate, :index)
def should_not_apply_before_filter_to_action(before_filter_name, action)
filter = find_maching_before_filter(before_filter_name)
assert_before_filter_not_applied(filter, action)
end

##example: should_apply_before_filters([:authenticate, :session_expiry])
def should_apply_before_filters(before_filter_names)
if(before_filter_names.nil? or before_filter_names.empty?)
assert false, "No Before Filter is Passed"
end
before_filter_names.each {|filter| should_apply_before_filter(filter)}
end

##example: should_apply_before_filter(:authenticate)
def should_apply_before_filter(before_filter_name)
filter = find_maching_before_filter(before_filter_name)
if(filter.nil?)
assert false, "no matching filter found for #{before_filter_name}"
end
assert filter.options.empty?, "the filter #{before_filter_name} has only/except options and does not apply to all actions"
end

private
#finds the matching BeforeFilter object
def find_maching_before_filter(before_filter_name)
filters = @controller.class.filter_chain()
if !filters.nil?
filters.each do |filter|
if(filter.is_a?(ActionController::Filters::BeforeFilter) and filter.method == before_filter_name)
return filter
end
end
end
return nil
end

#asserts a single BeforeFilter is applied on a single action
def assert_before_filter_applied(filter, action)
if(filter.nil? or action.nil?)
assert false
end

if(filter.options.empty?)
assert true
return
end
if(!filter.options[:only].nil?)
assert filter.options[:only].include?(action.to_s)
end
if(!filter.options[:except].nil?)
assert !filter.options[:except].include?(action.to_s)
end
end

#asserts a single BeforeFilter is not applied on a single action
def assert_before_filter_not_applied(filter, action)
if(filter.nil? or action.nil?)
assert false
end

if(filter.options.empty?)
assert false
end

if(!filter.options[:except].nil?)
assert filter.options[:except].include?(action.to_s)
end
if(!filter.options[:only].nil?)
assert !filter.options[:only].include?(action.to_s)
end
end
end
Now my test code looks like the following-
  def test_filters
should_apply_before_filters(:authenticate, :restrict_invalid_role)
end
I can use the other methods as well to get finer control if the before_filter is applied using :only or :except options. And I can use these helper methods across all my controller test classes, making the whole point of testing filters really neat and short.

If you are familiar with shoulda tests, you will find the above code following shoulda like naming conventions. I found the above code to strip a lot of your efforts, since you eliminate all test codes that safeguard your filters.

Hope it helps someone with similar need.

Comments

a_ludi
Thank you for your code base! This is quite useful to me, too. And probably to many others.

I've refactored your code a little:

http://pastebin.com/ybuAPfbF

Furthermore, I would advise to put this code into the test_helper.rb file, so all your tests can use it. Then you have to declare all methods except the assert* methods as private. The assert* methods should be public.

Forget Me Not! Object Oriented Design in Custom Exception

When designing custom exceptions, you may forget about old school OO fundamentals. As a reminder, lets take a look into the following custom exception classes.


StorySaveError
StoryDescopeNotAllowedError
StoryCompleteError
StoryNotFoundError
StoryDeleteError
StoryDeleteNotAllowedError

These exceptions are really useful in my application. But the bad thing is, they all derive from StandardError class, whereas there should be a base class, may be StoryError, which is more meaningful and useful. So, we can have the following-


class StoryError < StandardError
end
StorySaveError < StoryError
StoryDescopeNotAllowedError < StoryError
StoryCompleteError < StoryError
StoryNotFoundError < StoryError
StoryDeleteError < StoryError
StoryDeleteNotAllowedError < StoryError

With the addition of a base class for all Story related exceptions, I can write cleaner/better code.

  • When I am not interested about the specific error, I can just use rescue StoryError to catch ‘em all
  • I can place a common error handling routine for all Story related exceptions
  • I can add new exception types without altering the codes where the specific type of StoryError is insignificant

From my experience, I found that most people are not cautious about OO when desiging custom exceptions. (because they are exceptions!). Nonetheless, if you follow the OO guides, it will pay off for sure.

Comments

Sohan
Yes, that is another way. Usually, people use ErrorCode to designate such cases. For example, WebException has many error codes in .Net. One code denotes timeout, another denotes network failure and so on.
One quick point, I saw you added attr_accessor :message. message is already an attribute of the Exception class, the base class of all Exceptions. So, you need not define a message property again. Its there and you can use it for free!
Samiron Paul
Just sharing a little experience. A situation where user may be failed to delete a task for any of two type of restrictions. But in both case "TaskDeleteNotAllowed" type exception will be raising. Hence it will not be possible to show the exact reason to user. Now instead of being so conservative by creating a new class, we came out in the following way

Added a attribute in TaskDeleteNotAllowed:
Class TaskDeleteNotAllowed < StandardError
attr_accessor :message
end

Create an instance of the class while before raising:
exception = TaskDeleteNotAllowed.new

Setting custom message based on the error occurred and raise that:
exception.message = "Task is completed" #or any other message
raise exception

Of course rescuing the error as following:

rescue TaskDeleteNotAllowed => error
#show {error.message} in flash or write in log

That makes a proper sense to user whenever she fails to delete a task.

Anyway, being concerned with OO fundamentals in designing custom exception handlers is realized again.

Thanks for the post

Unit Test Eager Loading in Rails ActiveRecord Association

To avoid the n+1 problem, you need to use eager loading in ActiveRecord object associations. An easy implementation of eager loading can be done using named scope in the following way.

class User < ActiveRecord::Base
has_many :friends
named_scope :eager_load_friends, :include => :fiends
end
User.find(user_id).eager_load_friends
To unit test the named scope, you can use this following helper method (keep it in test_helper.rb, if you like) that I wrote for ScrumPad
def test_eager_loaded(model, association)
assert !model.instance_variable_get("@#{association.to_s}").nil?
end
You can then test your eager loading in the following way
def test_eager_load_friends
test_eager_loaded(User.find(1), :friends)
end
You can also use the shoulda plug-in if you like. For me, I think we should test the values returned by our named scope as opposed to shoulda approach, which tests if the code is written as expected.

Got another solution? I will appreciate if you share.

Comments

Ashrafuzzaman
Really useful.
And a clean way to reuse query.
Thanks for shearing

Implementing Template Method in Rails Controllers Using Module and Mixin

All rails controllers are subclasses of the ApplicationController class. A typical controller class declaration will look like the following-

class LoginController < ApplicationController
#the actions go here
end

With this basic information, I would like to state the problem first.


The Problem/Job in Hand

Add an action switch_project to all the controllers (> 20) of the ScrumPad code base. The implementations of the switch_project method will be same for all the controllers only other than the fact that, the switching destination will be different.


Analysis

Placing the switch_project action in the ApplicationController would be the best option. But, the methods of application controller are not accessible as actions. So, the following won’t work


class ApplicationController
def switch_project
if(is_valid_switch?)
logger.debug(“A switch is taking place”)
destination = get_destination(new_project_id)
redirect_to destination
end
end
end

if you hit http://server/login/switch_project you will get a server side error. However, if you instead place the switch_project inside the LoginController, it will work fine. But, of course at a cost. You need to copy/paste this method 20+ times as there are 20+ controllers with the same need! Horrible!


Again, as I said, the get_destination(new_project_id) is the only part that will be different for each of the controllers. So, we definitely find a template method here.


The Solution

If you need an introduction about Module and Mixin in Ruby, please read here at ruby-doc. We are going to use Mixin to implement the desired solution, efficiently.

So, I put the switch_project method in a module called, ProjectSwitchModule inside a new file at app/controllers/project_switch_module.rb like this-


module ProjectSwitchModule
def switch_project
if(is_valid_switch?)
logger.debug(“A switch is taking place”)
destination = get_destination(new_project_id)
redirect_to destination
end
end
def is_valid_switch?
#I determine if the switch is valid at this method and return boolean
end
end

To make it available to all my controllers, I include this module in just in the ApplicationController in the following way-


require ‘project_switch_module’
class ApplicationController
include ProjectSwitchModule
end

Also, to provide controller specific implementation of the get_destination(project_id) method, I am just writing this method in each of the controllers in the following way-


class LoginController
private
def get_destination(project_id)
#custom destination logic for LoginController
end
end
class MessageController
private
def get_destination(project_id)
#custom destination logic for MessageController
end
end

Now, if I invoke http://server/login/switch_project or http://server/message/switch_project I will get the result of the switch_project action. So, this gives us an elegant way to follow design patterns for efficient implementation. It will save a lot of my time in future when I need to change the switch_project method, since I just need to change at a single place instead of 20s.


Afterthoughts

If, for a controller the switch_project needs to be different from the template at the module, it is achieved simply by overriding the switch_project inside the controller. No worries!


I will appreciate any feedback on this article.

Comments

Sohan
Yes, in Ruby code block is a good way to implement templates. In most inumerator related templates, the library made extensive use of code blocks.
Ashrafuzzaman
Module and Mixin is an interesting way of implementing template.
“Code Block” can be one other alternative way.
Arif
Very good example of code reuse and single point of change.Thanks
Sohan
Thanks for your comment!
Anonymous
good post.