# Avoiding nested if statements

I occasionally find myself bumping into code like this (either in other projects or banging out initial prototypes myself):

 if @product.save
if current_member.role == "admin"
redirect_to krowd_path(@product)
else
redirect_to new_product_offer_path(@product)
end
else
render :new
end


What is a good way to avoid this type of situation all together?

• Use small functions that call each other and do not be afraid of multiple return points within one function. – Leonid Apr 22 '12 at 18:50
• I am not familiar with rails, but you can avoid one level of nesting by checking the exceptional/rare condition first and returning. – rahul Apr 22 '12 at 19:05
• codinghorror.com/blog/2006/01/flattening-arrow-code.html – Leonid Apr 22 '12 at 19:23

One suggestion is to make the roles two classes, initialize them based on the role and call the save function.

 class UserRole
def save(product)
redirect_to new_product_offer_path(product)
end
end
class AdminRole < UserRole
def save(product)
redirect_to krowd_path(product)
end
end
def create_role(r)
case r
else
return UserRole.new()
end
end

....
role = create_role(current_member.role)

if @product.save
role.save(@product)
else
render :new
end


If it matches to your requirements you could implement something like:

redirect_to_first_accessible(
krowd_path(@product),
new_product_offer_path(@product))


If you use something like CanCan gem, gererally it's defined which action is accessible to certain roles.

• I considered cancan for this case, but there are instances where it's not access based. The arrow code articlesmsup those generic cases, but cancan definitely helps separate when it comes to access. – cmhobbs Apr 30 '12 at 1:49