title: Running another controller action in Ruby on Rails
body: <p>This happened to me several times and I'm yet to find an acceptable solution.</p>
  
  <p>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.</p>
  
  <p>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</p>
  
  <p>Is there a better solution?</p>
  
  <p><strong>Update</strong>: 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.</p>
  
  <p>There are two models and controllers: posts and comments. A post has many reasons. An post is shown this way:</p>
  
  <pre><code>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 =&gt; :index, :status =&gt; :not_found
    end
  end
  
  private
  def set_posts
     @posts = Posts.get_all_public_posts
  end
  </code></pre>
  
  <p>The comments controller only has a create action:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>end</p>
  
  <p>The "Now what?" parts being the ones I don't have a good solution for.</p>