未定义的本地变量或方法ajax呈现部分rails

时间:2022-10-08 13:08:00

I'm trying to add ajax to my comment form submission and I've run into an error when I'm trying to render a partial and I don't know how to solve it. I have everything set up properly and comments get created fine. But then I try to render the partial for the comments and I get this error:

我试图将ajax添加到我的评论表单提交中,当我试图渲染一个部分时,我遇到了一个错误,我不知道如何解决它。我把所有的东西都设置好了,评论也被创建得很好。然后我试着给出评论的部分,我得到了这个错误:

undefined local variable or method `each' for #<#<Class:0xae4d760>:0xae59a78>

My create.js.erb

我create.js.erb

$("#comm_form_wrap").html("<%= escape_javascript(render :partial => "statuses/comment_form") %>");
$('#comment_box').val('');
$("#comments_wrap").html("<%= escape_javascript(render :partial => "statuses/comments") %>")

When I try to render statuses/comments is causing the error.

当我试图呈现状态/注释时,会导致错误。

Here's my partial:

这是我的部分:

<% @comments.each do |comment| %>
    <div class="com_con">
        <%= Rinku.auto_link(comment.content).html_safe %>
    </div>
<% end %>

So then I tried passing the variables like this

然后我试着像这样传递变量

$("#comments_wrap").html("<%= escape_javascript(render :partial => "statuses/comments", :locals => {:comment => comment}) %>")

but it gives this error

但它给出了这个误差

undefined local variable or method `each' for #<#<Class:0xae4d760>:0xae59a78>

Not sure what I'm missing here, I'm sure it's something small. Can anyone help me?

我不确定我错过了什么,我确定这是一件小事。谁能帮我吗?

View

视图

<% if member_signed_in? %>
    <div id="comm_form_wrap">
        <%= render "comment_form" %>
    </div>

    <div id="comments_wrap">
        <%= render "comments" %>
    </div>
<% end %>

**Edit**

* *编辑* *

comments_controller.rb

comments_controller.rb

class CommentsController < ApplicationController

before_filter :authenticate_member!
before_filter :load_commentable
before_filter :find_member

def index
   redirect_to root_path
end

def new
    @comment = @commentable.comments.new
end

def create
    @comment = @commentable.comments.new(params[:comment])
    @comment.member = current_member
    respond_to do |format|
        if @comment.save
          format.html { redirect_to :back }
          format.json
          format.js
        else
          format.html { redirect_to :back }
          format.json
          format.js
        end
    end 
end

def destroy
    @comment = Comment.find(params[:id])
    respond_to do |format|
        if @comment.member == current_member || @commentable.member == current_member
          @comment.destroy
          format.html { redirect_to :back }
        else
          format.html { redirect_to :back, alert: 'You can\'t delete this comment.' }
        end
    end 
end

private

def load_commentable
    klass = [Status, Medium, Project, Event, Listing].detect { |c| params["#{c.name.underscore}_id"] }
    @commentable = klass.find(params["#{klass.name.underscore}_id"])
end

def find_member
    @member = Member.find_by_user_name(params[:user_name])
end 

end

statuses_controller

statuses_controller

def show
    @status = Status.find(params[:id])
    @commentable = @status
    @comments = @commentable.comments.order('created_at desc').page(params[:page]).per_page(15)
    @comment = Comment.new
    respond_to do |format|
      format.html # show.html.erb
      format.json { redirect_to profile_path(current_member) }
      format.js
    end
end

Logs

日志

Processing by StatusesController#show as HTML
    Parameters: {"id"=>"86"}
    [1m[35mMember Load (1.0ms)[0m  SELECT "members".* FROM "members" WHERE "members"."user_name" IS NULL LIMIT 1
    [1m[36mStatus Load (0.0ms)[0m  [1mSELECT "statuses".* FROM "statuses" WHERE "statuses"."id" = ? LIMIT 1[0m  [["id", "86"]]
    [1m[35mComment Load (2.0ms)[0m  SELECT "comments".* FROM "comments" WHERE "comments"."commentable_id" = 86 AND "comments"."commentable_type" = 'Status' ORDER BY created_at desc LIMIT 15 OFFSET 0
    [#<Comment id: 82, content: "and why not try again ha", commentable_id: 86, commentable_type: "Status", member_id: 1, created_at: "2014-06-26 06:27:05", updated_at: "2014-06-26 06:27:05">]
    [1m[36mMember Load (1.0ms)[0m  [1mSELECT "members".* FROM "members" WHERE "members"."id" = 1 LIMIT 1[0m
    [1m[35mCACHE (0.0ms)[0m  SELECT "members".* FROM "members" WHERE "members"."id" = 1 LIMIT 1
    [1m[36m (0.0ms)[0m  [1mSELECT COUNT(*) FROM "comments" WHERE "comments"."commentable_id" = 86 AND "comments"."commentable_type" = 'Status'[0m
    Rendered statuses/_comment_form.html.erb (8.0ms)
    [1m[35mCACHE (0.0ms)[0m  SELECT "members".* FROM "members" WHERE "members"."id" = 1 LIMIT 1
    Rendered statuses/_comments.html.erb (95.0ms)
    Rendered statuses/show.html.erb within layouts/application (406.0ms)
    Rendered layouts/_query.html.erb (108.0ms)
    Rendered search/_search.html.erb (22.0ms)
    Rendered layouts/_menu.html.erb (592.0ms)
Completed 200 OK in 2956ms (Views: 2312.1ms | ActiveRecord: 10.0ms | Solr: 0.0ms)

2 个解决方案

#1


3  

Problem is your partial is calling @comments.each:

问题是你的部分呼叫@comments.each:

<% @comments.each do |comment| %>

2 issues:

2个问题:

  1. @comments doesn't exist
  2. @comments不存在
  3. Partials need to use local variables (they can't rely on @instance vars)
  4. 局部变量需要使用局部变量(它们不能依赖于@instance vars)

--

- - -

Partials

分音

You'll be best doing this:

你最好这样做:

<%= render partial"statuses/comments", collection: @comments, as: comment %> 

There is a little-known piece of functionality in Rails' partials which allows you to basically "reload" the partial for each member of a collection.

Rails的部分中有一个鲜为人知的功能,它允许您为集合中的每个成员“重载”部分。

The reason this is important is because it cuts out a LOT of code from your partial. If you use the partial I posted above, you'll only need this code inside the partial:

这之所以重要,是因为它从您的部分中删除了许多代码。如果你使用我上面贴出的部分,你只需要这个代码在部分:

#app/views/statuses/_comments.html.erb
<div class="com_con">
    <%= Rinku.auto_link(comment.content).html_safe %>
</div>

If you set the correct @instance variable, and pass it into the collection option of the partial, Rails will basically reload the partial in a loop, like you have with the .each loop now

如果您设置了正确的@instance变量,并将其传递到分部的集合选项中,那么Rails基本上会在循环中重新加载分部,就像现在的.each循环一样

This will also work for singular items:

这也适用于单一项目:

<%= render partial: "statuses/comments", object: @comment, as: comment %>

--

- - -

Instance Variable

实例变量

The second issue is the setting of your instance variable

第二个问题是实例变量的设置

In your controller, you are not setting the @comments instance variable. This means you cannot load the contents of this variable into your view, consequently causing an issue like you've got

在控制器中,您没有设置@comments实例变量。这意味着您不能将该变量的内容加载到您的视图中,从而导致您遇到的问题

The way to fix this is very simple - use @instance variables you have set in your controller!

解决这个问题的方法非常简单——使用您在控制器中设置的@instance变量!

--

- - -

Escape

逃避

You may also need to look at how to escape quotes in your JS:

您可能还需要了解如何在您的JS中转义引号:

$("#comments_wrap").html("<%= escape_javascript(render :partial => \"statuses/comments\", :locals => {:comment => comment}) %>")

I'm not sure if this is applicable in this case, but I do know if you encapsulated quotes inside another set, you'll get errors from your JS

我不确定这是否适用于这种情况,但是我知道如果您将引号封装在另一个集合中,您将会从您的JS中得到错误。

#2


0  

The answer above helped me solve this. Rendering the comments as a collection helped me render the partial through ajax and I also needed to define @comments in my create action in my comments_controller as well to ensure it doesn't render blank.

上面的答案帮助我解决了这个问题。将注释呈现为一个集合,帮助我通过ajax呈现部分内容,我还需要在我的comments_controller中定义@comments,以确保它不会呈现空白。

#1


3  

Problem is your partial is calling @comments.each:

问题是你的部分呼叫@comments.each:

<% @comments.each do |comment| %>

2 issues:

2个问题:

  1. @comments doesn't exist
  2. @comments不存在
  3. Partials need to use local variables (they can't rely on @instance vars)
  4. 局部变量需要使用局部变量(它们不能依赖于@instance vars)

--

- - -

Partials

分音

You'll be best doing this:

你最好这样做:

<%= render partial"statuses/comments", collection: @comments, as: comment %> 

There is a little-known piece of functionality in Rails' partials which allows you to basically "reload" the partial for each member of a collection.

Rails的部分中有一个鲜为人知的功能,它允许您为集合中的每个成员“重载”部分。

The reason this is important is because it cuts out a LOT of code from your partial. If you use the partial I posted above, you'll only need this code inside the partial:

这之所以重要,是因为它从您的部分中删除了许多代码。如果你使用我上面贴出的部分,你只需要这个代码在部分:

#app/views/statuses/_comments.html.erb
<div class="com_con">
    <%= Rinku.auto_link(comment.content).html_safe %>
</div>

If you set the correct @instance variable, and pass it into the collection option of the partial, Rails will basically reload the partial in a loop, like you have with the .each loop now

如果您设置了正确的@instance变量,并将其传递到分部的集合选项中,那么Rails基本上会在循环中重新加载分部,就像现在的.each循环一样

This will also work for singular items:

这也适用于单一项目:

<%= render partial: "statuses/comments", object: @comment, as: comment %>

--

- - -

Instance Variable

实例变量

The second issue is the setting of your instance variable

第二个问题是实例变量的设置

In your controller, you are not setting the @comments instance variable. This means you cannot load the contents of this variable into your view, consequently causing an issue like you've got

在控制器中,您没有设置@comments实例变量。这意味着您不能将该变量的内容加载到您的视图中,从而导致您遇到的问题

The way to fix this is very simple - use @instance variables you have set in your controller!

解决这个问题的方法非常简单——使用您在控制器中设置的@instance变量!

--

- - -

Escape

逃避

You may also need to look at how to escape quotes in your JS:

您可能还需要了解如何在您的JS中转义引号:

$("#comments_wrap").html("<%= escape_javascript(render :partial => \"statuses/comments\", :locals => {:comment => comment}) %>")

I'm not sure if this is applicable in this case, but I do know if you encapsulated quotes inside another set, you'll get errors from your JS

我不确定这是否适用于这种情况,但是我知道如果您将引号封装在另一个集合中,您将会从您的JS中得到错误。

#2


0  

The answer above helped me solve this. Rendering the comments as a collection helped me render the partial through ajax and I also needed to define @comments in my create action in my comments_controller as well to ensure it doesn't render blank.

上面的答案帮助我解决了这个问题。将注释呈现为一个集合,帮助我通过ajax呈现部分内容,我还需要在我的comments_controller中定义@comments,以确保它不会呈现空白。