Your controllers are procedural. This is not necessarily your fault- the code you get from rails scaffolding is procedural, setting the precedent that it is ok.
Here is a snippet from standard scaffold code:
class PostsController
def create
@post = Post.new(params)
if @post.save
flash[:success] = "#{post.title} posted"
redirect_to posts_path(post)
else
render :new
end
end
end
For scaffolded code, this is a fine tradeoff, it is only meant to be a starting point. Here is what it could look like:
class PostsController
def create
creator = PostCreator.new(self)
creator.create_with(params[:post])
end
def post_creation_succeeded(post)
flash[:success] = "#{post.title} posted"
redirect_to posts_path(post)
end
def post_creation_failed(post)
@post = post
render :new
end
end
This is taken from Matt Wynne's Hexagonal Rails talk at GoRuCo 2012, embedded below
To summarize, rails projects start out fast, where changes are fun and exciting, but upfront velocity is more than paid for in developer pain. Service objects (in the case presented above) allow us to isolate ourselves from Rails in a very fundamental way. Beyond just isolating your logic from the controller, it allows for seams in which to generate events (:post_creation_succeeded is a pretty good event name)
37signals products (Basecamp, Campfire, Highrise) are optimized for the 80% of the functionality gained by 20% of the work, and Rails shows for it. The initial amount of time is great, but for businesses that want to be in the (like mine), this becomes cumbersome. I would not recommend abandoning rails entirely because the common use case is unsustainable. Rails provides tools whose existence is important, and is mostly invisible to the developer. We just need to use object oriented programming concepts as users
This post was made in order to garner support for the tortoise in an intra-office competition. Save my development team- vote for the tortoise (http://tortoisevshare.nationbuilder.com/team_tortoise)