views:

87

answers:

1

I have a rails 3 application very similar to the one in Railscasts episode #229 the only difference is that in my code Articles is called Posts and I have a nested route:

routes.rb:

Myapp::Application.routes.draw do
  resources :posts do
    resources :comments
  end
  root :to => "tags#index"
end

I receive this error in the terminal:

[2010-09-13 00:22:13] ERROR NoMethodError: undefined method `page_cache_extension' for ActionController::Base:Class
        /usr/local/lib/ruby/gems/1.9.1/gems/actionpack-3.0.0/lib/action_dispatch/middleware/static.rb:21:in `call'
        /usr/local/lib/ruby/gems/1.9.1/gems/railties-3.0.0/lib/rails/application.rb:168:in `call'
        /usr/local/lib/ruby/gems/1.9.1/gems/railties-3.0.0/lib/rails/application.rb:77:in `method_missing'
        /usr/local/lib/ruby/gems/1.9.1/gems/railties-3.0.0/lib/rails/rack/log_tailer.rb:14:in `call'
        /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.2.1/lib/rack/content_length.rb:13:in `call'
        /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.2.1/lib/rack/handler/webrick.rb:52:in `service'
        /usr/local/lib/ruby/1.9.1/webrick/httpserver.rb:111:in `service'
        /usr/local/lib/ruby/1.9.1/webrick/httpserver.rb:70:in `run'
        /usr/local/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'


    Started GET "/posts/comments.js?post_id=1&after=1284333896" for 192.168.1.108 at 2010-09-13 00:22:15 +0000
        Processing by PostsController#show as JS
        Parameters: {"post_id"=>"1", "after"=>"1284333896", "id"=>"comments"}
        SQL (4.8ms)   SELECT name
     FROM sqlite_master
     WHERE type = 'table' AND NOT name = 'sqlite_sequence'

        SQL (1.5ms)   SELECT name
     FROM sqlite_master
     WHERE type = 'table' AND NOT name = 'sqlite_sequence'
        Post Load (0.7ms)  SELECT "posts".* FROM "posts" WHERE ("posts"."id" = 0) LIMIT 1
    Completed   in 392ms

    ActiveRecord::RecordNotFound (Couldn't find Post with ID=comments):
        app/controllers/posts_controller.rb:8:in `show'

    Rendered /usr/local/lib/ruby/gems/1.9.1/gems/actionpack-3.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.erb (11.4ms)
    Rendered /usr/local/lib/ruby/gems/1.9.1/gems/actionpack-3.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (49.3ms)
    Rendered /usr/local/lib/ruby/gems/1.9.1/gems/actionpack-3.0.0/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (92.4ms)

posts_controller.rb:8:

@post = Post.find(params[:id])

Comments_Controller index method:

def index @comments = Comment.where("post_id = ? and created_at > ?", params[:post_id], Time.at(params[:after].to_i + 1)) end

application.js:

$(function() {
  if ($("#comments").length > 0) {
    setTimeout(updateComments, 10000);
  }
});

function updateComments () {
  var post_id = $("#post").attr("data-id");
  if ($("#comments").length > 0) {
    var after = $(".comment:last-child").attr("data-time");
  } else {
    var after = "0";
  }
  $.getScript("/comments.js?post_id=" + post_id + "&after=" + after)
  setTimeout(updateComments, 10000);
}

I have a hunch that the problem is the nested route. How do I get the Javascript in application.js to recognize the nested route?

EDIT:

posts/show.html.erb:

<div id="post" data-id="<%= @post.id %>">
  <%= link_to @post.title, @post %>
  <%= simple_format @post.content %>

  <p><%= link_to "Back to Posts", posts_path %></p>

  <% unless @post.comments.empty? %>
    <h2><%= pluralize(@post.comments.size, 'comment') %></h2>

    <div id="comments">
      <%= render @post.comments %>
    </div>
  <% end %>
</div>

<div id="replyform">
  <%= render "comments/form" %>
</div>

comments/_form.html.erb:

<%= form_for([@post, Comment.new], :html => { :multipart => true }) do |f| %>
  <fieldset>
    <fieldset id="optional">
      <%= f.label :commenter, "name (optional)" %>
      <%= f.text_field :commenter, :placeholder => "name (optional)" %>

      <%= f.label :email, "email (optional)" %>
      <%= f.email_field :email, :placeholder => "email (optional)" %>
    </fieldset>
  </fieldset>
  <fieldset>
    <%= f.label :body, "reply " %>
    <%= f.text_area :body, :placeholder => "reply" %>
    <%= f.submit 'reply' %>
  </fieldset>
<% end %>

After changing the line mentioned in application.js to:

$.getScript("/posts/" + post_id + "/comments/&after=" + after)

I get the error in my terminal:

Started GET "/posts/1/comments/&after=1284388076" for 192.168.1.108 at 2010-09-13 14:28:29 +0000
  Processing by CommentsController#show as JS
  Parameters: {"post_id"=>"1", "id"=>"&after=1284388076"}
Completed   in 28ms

ActionView::MissingTemplate (Missing template comments/show with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:js, :"*/*"], :locale=>[:en, :en]} in view paths "/media/usb0/myapp/app/views"):


Rendered /usr/local/lib/ruby/gems/1.9.1/gems/actionpack-3.0.0/lib/action_dispatch/middleware/templates/rescues/missing_template.erb within rescues/layout (5.9ms)

SECOND EDIT: comments/index.js.erb:

<% unless @comments.empty? %>
  $("#comments").append("<%=raw escape_javascript(render(@comments)) %>");
<% end %>

comments/show.js.erb:

$("#comments").append("<%=raw escape_javascript(render(@comments)) %>");

comments_controller.rb:

def show
  @comments = Comment.where("post_id = ? and created_at > ?", params[:post_id], Time.at(params[:after].to_i + 1))
end
+2  A: 

1. Check the getScript call

$.getScript("/comments.js?post_id=" + post_id + "&after=" + after)

This line refers to a flat route for comments. Maybe it should be like

$.getScript("/posts/" + post_id + "/comments?after=" + after)

2. Check your views.

The error ActiveRecord::RecordNotFound (Couldn't find Post with ID=comments) tells me that the incorrect thing in this setup may be the data-id attribute on the that ends up in your rendered view. It should be the id of the post. I can tell more if you share the erb file as well.

edgerunner
view code added. thank you for your help.
Ok, now I'm sure that it is the first one... Fix that js line and it should be ok.
edgerunner
Looks like you are missing your template file at `./app/views/comments/index.js.erb`. It is supposed to contain the replacement data.
edgerunner
Posts#show now updates the comments via ajax, but instead of pulling in just the new comment(s), it appends all existing comments below the previous ones. Code updated above.
edgerunner
This did it! Thank so much for being patient with me. Have a great day edgerunner!
You're welcome.
edgerunner