views:

71

answers:

2

I'm creating a basic message board app with Rails 3. I want posts to be created with UJS/jQuery (submit the post with AJAX and clear the form). I thought this would be simple but I'm getting this error:

Rendered posts/create.js.erb (64.5ms)
Completed   in 1771ms

ActionView::Template::Error (undefined local variable or method `posts' for #<#<Class:0x1d681d0>:0x1d66f10>):
    1: $("#posts").html("<%= escape_javascript(render(:partial => posts)) %>");
    2: $("#form").html("<%= escape_javascript(render 'form') %>");
  app/views/posts/create.js.erb:1:in `_app_views_posts_create_js_erb__431255654_15413772__591965598'
  app/controllers/posts_controller.rb:41:in `create'

Rendered /usr/local/lib/ruby/gems/1.9.1/gems/actionpack-3.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.erb (10.5ms)
Rendered /usr/local/lib/ruby/gems/1.9.1/gems/actionpack-3.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (53.8ms)
Rendered /usr/local/lib/ruby/gems/1.9.1/gems/actionpack-3.0.0/lib/action_dispatch/middleware/templates/rescues/template_error.erb within rescues/layout (95.0ms)

layouts/application.html.erb:

<!DOCTYPE html>
<html>
  <head>
    <title><%= @title || controller.action_name %></title>
    <%= stylesheet_link_tag 'style' %>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
    <%= javascript_include_tag 'jquery.timeago','jquery.watermark', 'rails' %>
    <%= csrf_meta_tag %>
  </head>
  <body>
    <container>
      <%= render "shared/nav" %>
      <section id="content">
        <%- flash.each do |name, msg| -%>
          <%= content_tag :div, msg, :id => "flash_#{name}" %>
        <%- end -%>
        <%= yield %>
      </section>
      <%= render "shared/footer" %>
    </container>
  </body>
</html>

posts/index.html.erb:

<div id="posts">
  <%= render 'posts' %>
</div>
<%= will_paginate @posts, :previous_label => "previous", :next_label => "next" %>
<div id="form">
  <%= render 'form' %>
</div>

posts/_posts.html.erb:

<%- for post in @posts -%>
   ...
<%- end -%>

posts/_form.html.erb:

<%= form_for :post, :remote => true, :url => { :controller => :posts, :action => "create" } do |f| %>

  <%= f.label :title, "title" %>
  <%= f.text_field :title, :placeholder => "title" %>

  <%= f.label :content, "message" %>
  <%= f.text_area :content, :placeholder => "message" %>

  <%= f.submit 'post' %>

<% end %>

posts/create.js.erb:

$("#posts").html("<%= escape_javascript(render(:partial => posts)) %>");
$("#form").html("<%= escape_javascript(render 'form') %>");

posts_controller.rb:

class PostsController < ApplicationController
  before_filter :find_post, :only => [:show, :edit, :update, :destroy]
  respond_to :html, :js

  def index
    @title = "chat"
    @posts = Post.paginate :page => params[:page], :order => "updated_at DESC"
    respond_to do |format|
      format.html
      format.js
    end
  end

  # ...

  def new
    @post = Post.new
    respond_to do |format|
      format.html
      format.js
    end
  end

  def create
    @post = Post.new(params[:post])
    respond_to do |format|
      if @post.save
        flash[:notice] = "Created \"#{@post.title}\""
        format.html { redirect_to(posts_url) }
        format.js
          else
        flash[:error] = "Title, tag and message required"
        format.html { redirect_to(posts_url) }
        format.js
      end
    end
  end

  # ...

  private

  def find_post
    @post = Post.find(params[:id])
    @comments = @post.comments
  end
end

I'm using Rails 3.0.0, and Ruby 1.9.2. Not sure what the issue is.

A: 

Just making sure, you did install the jQuery UJS stuff right? I imagine you did, since you tagged it as such, but you made no mention of it in your post. Again, just making sure!

Jorge Israel Peña
that's what the `'rails'` is in `application.html.erb`
I manually the file from github and put in in my javascripts directory.
Did you follow the instructions listed here? http://github.com/rails/jquery-ujs/blob/master/README.rdoc
Jorge Israel Peña
+2  A: 

in posts/create.js.erb

$("#posts").html("<%= escape_javascript(render(:partial => posts)) %>");

should be:

$("#posts").html("<%= escape_javascript(render "posts") %>");

There's no definition for posts, so if you give it a string, it will evaluate to the partial posts/_posts.html.erb

Aside, for using jQuery instead of prototype in a rails 3 application, jquery-rails is awesome.

Dan McNevin