Show validation errors in partial form with polymorphic model

Viewed 41

I want my users to be able to create Comments on Posts and Profiles. This is the reason I have implemented the Comment model as a polymorphic model. I would like to show the users any validation errors within a partial form that is rendered on a Post. My problem is that I am new to rails and don't quiet get it why I don't get any errors displayed.

controllers/comments_controller.rb

class CommentsController < ApplicationController
    # GET /comments/new
    def new
        @comment = @commentable.comments.new
    end

    # POST /comments or /comments.json
    def create
        @comment = @commentable.comments.new(comment_params)
        @comment.profile = current_user.profile

        respond_to do |format|
            if @commentable.save
                format.html { redirect_to @commentable, notice: "Comment was successfully created." }
            else
                format.html { redirect_to @commentable, status: :unprocessable_entity }
            end
        end
    end

    private

    # Use callbacks to share common setup or constraints between actions.
    def set_comment
        @comment = Comment.find(params[:id])
    end
end

controllers/posts/comments_controller.rb

class Posts::CommentsController < CommentsController
    before_action :set_commentable

    def create
        super
    end

    private

    def set_commentable
        @commentable = Post.find_by_url_title(params[:post_url_title])
    end
end

views/posts/show.html.erb

<%= render "/shared/navbar" %>

<div class="container">
    <%= render @post %>
    <h3>COMMENTS</h3>
    <%= render partial: "comments/form", local: { commentable: @post } %>
    <%= render @post.comments %>
</div>

views/comments/_form.html.erb

<%= form_with(model: [@commentable, Comment.new], class: "contents") do |form| %>
    <%= render "/shared/error_messages", errors: @commentable.errors, title: "Comment creation failed" %>

    <%= form.label :body, "Comment" %>
    <%= form.text_area :body, class: "w-full" %>

    <div class="inline">
        <%= form.submit class: "btn-primary" %>
    </div>
<% end %>
1 Answers

You have some syntax issues with partials. See this guide.

Try turning this:

<%= render partial: "comments/form", local: { commentable: @post } %>

into this:

<%= render partial: "comments/form", locals: { commentable: @post } %>


and this:

<%= form_with(model: [@commentable, Comment.new], class: "contents") do |form| %>

into this:

<%= form_with(model: [commentable, Comment.new], class: "contents") do |form| %>


But also, redirect_to is not what you want to use if @commentable fails to save:

respond_to do |format|
  if @commentable.save
    format.html { redirect_to @commentable, notice: "Comment was successfully created." }
  else
    # when you redirect_to @commentable, you are probably sending the browser to Posts::CommentsController#show
    # and once that controller loads, the @commentable variable gets overwritten and the errors are lost
    # format.html { redirect_to @commentable, status: :unprocessable_entity }
    format.html { render 'posts/show', status: :unprocessable_entity }
  end
end
Related