使用Ajax并获取NoMethodError(未定义的方法`[]'为nil:NilClass)

时间:2016-07-04 01:17:13

标签: ruby-on-rails ajax

我是Rails和jQuery的新手,我感觉有点过头了。我只想制作一个单页应用程序,让我记录我朋友所说的攻击性内容,然后使用向上和向下的系统来订购它们。一旦使用Ajax更新分数,我很难找到重新排序的帖子。现在我只是试图通过downvote动作实现这一点。我试图在此处包含所有相关信息,但如果我需要包含更多信息,请与我们联系。

错误

Completed 500 Internal Server Error in 39ms (ActiveRecord: 3.2ms)

NoMethodError (undefined method `[]' for nil:NilClass):
  app/views/posts/_posts.html.erb:3:in `_app_views_posts__posts_html_erb__962868812775721276_70166010949980'
  app/views/posts/downvote.js.erb:2:in `_app_views_posts_downvote_js_erb__4067496276046646679_70165971968540'
  app/controllers/posts_controller.rb:39:in `downvote'


  Rendered /Users/shaneboyar/.rvm/gems/ruby-2.3.1@myapp/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/_source.erb (3.0ms)
  Rendered /Users/shaneboyar/.rvm/gems/ruby-2.3.1@myapp/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/_trace.text.erb (1.5ms)
  Rendered /Users/shaneboyar/.rvm/gems/ruby-2.3.1@myapp/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/_request_and_response.text.erb (0.8ms)
  Rendered /Users/shaneboyar/.rvm/gems/ruby-2.3.1@myapp/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/diagnostics.text.erb (47.0ms)

帖子控制器

class PostsController < ApplicationController

def index
  @new_post = Post.new
  @all_posts = Post.order(score: :desc).all 
end

def create
@new_post = Post.new(post_params)
    if @new_post.save
        flash[:success] = "Yeah... he probably would say that."
        redirect_to root_path
    end
end

def destroy
  @post = Post.find(params[:id])
  @post.delete
  respond_to do |format|
    format.html { redirect_to root_path }
    format.js
  end
end

def upvote
  @post = Post.find(params[:id])
  @post.score += 1
  @post.save
  respond_to do |format|
    format.html { redirect_to root_path }
    format.js
  end
end

def downvote
  @post = Post.find(params[:id])
  @post.score -= 1
  @post.save
  respond_to do |format|
    format.html { redirect_to root_path }
    format.json { render json: @post }
    format.js
  end
end

查看/帖子/ _Index.html.erb

<div class="jumbotron center">
  <div class="container">
    <h1>@MattBatt</h1>
    <h4>Things Matt has probably said at one point.</h4>
  </div>
</div>

<div class="container">

<!--BEGIN FORM -->  
  <%= form_for(@new_post) do |f| %>

    <div class="form-group">            
      <div class="field">
        <%= f.label :'What\'d that man say now?' %><br>
        <%= f.text_area :comment, :class => 'form-control' %>
      </div>

    </div> 
        <div class="actions">
        <%= f.button "Create", :class => 'btn btn-default btn-lg btn-block' %>
        </div> 

  <% end %>
<!-- END FORM -->

<!--BEGIN ALERT -->
  <% flash.each do |message_type, message| %>
    <div class="alert alert-<%= message_type %>"><%= message %></div>
<% end %>
<!--END ALERT -->

<!--BEGIN POSTS -->  
 <%= render 'posts' %>
<!--END POSTS -->

</div>

观看/帖子/ _Posts.html.erb (我觉得这可能是一团糟?)

<div class="container-fluid comments" id="comments"> 
  <ul>
    <% @all_posts[0..9].each do |p| %>
      <li class="row">
        <div class="col-sm-2">
          <div class='post-<%=p.id%>-score score'><%= p.score %></div>
          <div class="voters">
            <div class="upvoter"><%= link_to( image_tag("upArrow.png"), upvote_post_path(p), method: :patch, remote: true, :class => 'upvoter_button') %></div>
            <div class="downvoter"><%= link_to( image_tag("downArrow.png"), downvote_post_path(p), method: :patch, remote: true, :class => 'downvoter_button') %></div>
          </div>
        </div>
        <div class="comment col-sm-9">
          <%= p.comment %>
          <div class="timestamp">Posted <%= time_ago_in_words(p.created_at) %> ago.
          <% if Rails.env.development? %>
            <%= link_to "delete", p, method: :delete, remote: true, :class => 'deleter' %>
          <% end %>
          </div>
        </div>
      </li>
    <% end %>
  </ul>
</div>

的routes.rb

Rails.application.routes.draw do

  root 'posts#index'

  get 'posts/index'

  get 'posts/create'

  resources :posts do
  member do
    patch 'upvote'
    patch 'downvote'
  end
end

查看/帖子/ downvote.js.erb

$(".post-<%=@post.id%>-score").html('<%= @post.score %>');
$("#comments").html("<%= escape_javascript(render('posts/posts')) %>");

感谢。我试着在这里查找答案,虽然看起来很多人都会遇到类似的错误,但是在不同的情况下。任何建议都会非常感激。

1 个答案:

答案 0 :(得分:0)

如果您想重新订购downvote/upvote上的帖子,我假设您正在使用Rails这样做,尽管我认为您可以有效地使用JS。< / p>

您收到错误的原因是您的@all_posts操作中未在控制器中设置downvote

您可以将其添加到before_action来电。

before_action :set_all_posts, only: [:index, :downvote, :upvote]
def set_all_posts
  @all_posts = Post.order(score: :desc)
end