This happened to me several times and I'm yet to find an acceptable solution.
I have a form in the home page of a site, that forms points to another controller which actually does the job of processing the data. When the form is submitted successfully, the other controller sends you back to the homepage with a nice flash[:notice] message, and that's the end of it.
When there's a validation issue it becomes a problem. What I'd like to do is to show the homepage with the form with the validation errors. The naive solution normally mention is that you can render another template, but showing the homepage is much more than rendering a template, it has a lot of functionality. The only way to render that template is to copy and paste the functionality in this other controller action, or maybe taking all functionality away from a controller, which is not very nice either
Is there a better solution?
Update: I understand people saying that the controller actions should be smaller and call another method, but in practice, I don't see how to achieve it. I'm going to post a real example out of a web site I did.
There are two models and controllers: posts and comments. A post has many reasons. An post is shown this way:
def index
set_posts # sets @posts
end
def show
@post = Post.find_by_slug(params[:id])
@comment = Comment.new
if not @post
flash[:error] = "'#{params[:id]}' does't exist"
set_posts
render :action => :index, :status => :not_found
end
end
private
def set_posts
@posts = Posts.get_all_public_posts
end
The comments controller only has a create action:
def create
@comment = Comment.new(params[:comment])
@comment.post = Post.find_by_slug params['post_id']
if not @comment.post
# Now what?
# We should here call PostsController.set_posts and render views/posts/index
end
if @reason.save
flash[:notice] = 'Thank you for your message.'
redirect_to(@reason.item)
else
# Now what?
# We should here call PostsController.show without overriding the @comment
end
end
end
The "Now what?" parts being the ones I don't have a good solution for.