Adam Zerner
Adam Zerner

Reputation: 19238

Why isn't my AJAX form working?

I'm learning Rails and am trying to implement AJAX to my sample app. I'm following this Railscast and I think I'm doing everything it said, but it isn't working and I can't seem to figure out why.

  1. I've got remote: true.
  2. I have the respond_to block where I respond to the js format.
  3. I render create.js.erb if the format is js.

The code in create.js.erb isn't being executed. I've got a alert('test'); that isn't appearing. However, if I refresh the page, the new comment is shown. What am I doing wrong?

_form.html.erb

<%= simple_form_for [@article, @comment], remote: true do |f| %>
    <%= f.input :author, label: 'Name' %>
    <%= f.input :body %>
    <%= f.button :submit %>
<% end %>

comments_controller.rb

class CommentsController < ApplicationController
    def create
        @comment = Comment.new(comment_params)
        @comment.article_id = params[:article_id]
        if @comment.save
            respond_to do |f|
                f.html { redirect_to article_path(params[:article_id]), notice: 'Comment created!' }
                f.js { render 'create.js.erb' }
            end
        else
            redirect_to article_path(params[:article_id]), warning: 'Unable to create comment.'
        end
    end

    private

        def comment_params
            params.require(:comment).permit(:author, :body)
        end
end

create.js.erb

$(document).ready(function() {
    alert('test');
    $('#comments').html("<%= j render('comments/list_comments') %>");
});

stack trace

POST http://localhost:3000/articles/2/comments 500 (Internal Server Error) jquery.js?body=1:9667
send jquery.js?body=1:9667
jQuery.extend.ajax jquery.js?body=1:9212
$.rails.rails.ajax jquery_ujs.js?body=1:81
$.rails.rails.handleRemote jquery_ujs.js?body=1:157
(anonymous function) jquery_ujs.js?body=1:364
jQuery.event.dispatch jquery.js?body=1:4625
elemData.handle

updated stack trace last line is slightly different

POST http://localhost:3000/articles/2/comments 500 (Internal Server Error) jquery.js?body=1:9667
send jquery.js?body=1:9667
jQuery.extend.ajax jquery.js?body=1:9212
$.rails.rails.ajax jquery_ujs.js?body=1:81
$.rails.rails.handleRemote jquery_ujs.js?body=1:157
(anonymous function) jquery_ujs.js?body=1:364
jQuery.event.dispatch jquery.js?body=1:4625
elemData.handle jquery.js?body=1:4293

Rails console output

Started POST "/articles/2/comments" for 127.0.0.1 at 2014-05-19 17:12:16 -0400
Processing by CommentsController#create as JS
  Parameters: {"utf8"=>"✓", "comment"=>{"author"=>"hhh", "body"=>"hhh"}, "commit"=>"Create Comment", "article_id"=>"2"}
   (0.1ms)  begin transaction
  SQL (2.0ms)  INSERT INTO "comments" ("article_id", "author", "body", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["article_id", 2], ["author", "hhh"], ["body", "hhh"], ["created_at", Mon, 19 May 2014 21:12:16 UTC +00:00], ["updated_at", Mon, 19 May 2014 21:12:16 UTC +00:00]]
   (31.2ms)  commit transaction
  Rendered comments/_list_comments.html.erb (1.3ms)
  Rendered comments/create.js.erb (2.7ms)
Completed 500 Internal Server Error in 56ms

ActionView::Template::Error (undefined method `each' for nil:NilClass):
    1: <div id="comments">
    2:  <% @comments.each do |comment| %>
    3:      <hr />
    4:      <p><small><%= comment.author %></small></p>
    5:      <p><%= comment.body %></p>
  app/views/comments/_list_comments.html.erb:2:in `_app_views_comments__list_comments_html_erb__1695291160912137125_70349468259020'
  app/views/comments/create.js.erb:1:in `_app_views_comments_create_js_erb___4307677746730482839_70349467492020'
  app/controllers/comments_controller.rb:6:in `create'

_list_comments.html.erb

<div id="comments">
    <% @comments.each do |comment| %>
        <hr />
        <p><small><%= comment.author %></small></p>
        <p><%= comment.body %></p>
    <% end %>
</div>

Upvotes: 0

Views: 206

Answers (1)

Matheus Lima
Matheus Lima

Reputation: 2143

Try this:

on your comments_controller:

f.js { @comments = Comment.all }

on your create.js.erb:

$("#comments").html("<%= escape_javascript(render :partial => 'comments/list_comments', :locals => {:comments => @comments}) %>");

Upvotes: 1

Related Questions