berkes
berkes

Reputation: 27583

Prefill form from associated object on error in Rails

I have a Post that has_many :comments and a Comment that belongs_to :post. On /posts/:id (the post show method) I render a form where users can leave comments.

It all works, validations, tests and posting is just fine. Only thing missing is how to re-render the POSTed data on validation errors.

The (simplified) code for this is:

#app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def index
    @posts = Post.all_published(params[:page])
    @title = "Blog"
  end

  def show
    @post = Post.where({:published => true}).find(params[:id])
    @comment = Comment.new(:post => @post)
    @title = @post.title
  end
end

#app/controllers/comments_controller.rb
class CommentsController < ApplicationController
  def create
    @comment = Comment.new(params[:comment])
puts @comment

    if @comment.save
      flash[:notice] = 'Comment was successfully created.'
      redirect_to(@comment.post)
    else
      flash[:notice] = "Error creating comment: #{@comment.errors}"
      redirect_to(@comment.post)
    end
  end
end

#app/views/posts/show.haml
.html renders Post contents.

- form_for @comment do |f|
  = f.hidden_field :post_id
  = f.text_area :body
  = f.text_field :name
  .some more fields.

I expect the solution to be either in some magical declaration in the comments_controller.rb, part

   else
      flash[:notice] = "Error creating comment: #{@comment.errors}"
      redirect_to(@comment.post)
    end

Or in the PostsController.show where I prepare the @comment. Should I set that @comment conditional and fill it with some magic variable on errors? Or did I make some entirely different mistake?

Upvotes: 0

Views: 1114

Answers (1)

Rishav Rastogi
Rishav Rastogi

Reputation: 15492

If you redirect, that data is usually lost, thats why in most cases in create create actions you would have noticed that in the false scenario, render not redirect_to.

So instead you could just try,

 flash[:notice] = ""Error creating comment: #{@comment.errors}"
 render :template => "posts/show"
 @post = @comment.post
 # you may need to pre-populate the instance variables used inside PostsController#show 

Upvotes: 1

Related Questions