为什么我在用户中获得NoMethodError #index错误(Ruby on Rails)

时间:2013-03-04 07:56:58

标签: ruby-on-rails ruby ruby-on-rails-3

我看了很多其他线程并花了几个小时来查看它,但我仍然无法弄明白。

我在另一个视图页面使用相同的代码行

这是错误:

app/views/users/_user.html.erb第4行引出:

undefined method `microposts' for nil:NilClass

如果您熟悉它,可以从Rubytutorial演示应用程序中获取。此代码在views\users\show.html.erb中使用,我试图查看它是否适用于views\users\ _user.html.erb,但我收到错误。

我正在重复使用的代码是:

<%= @user.microposts.count %>

这是调用部分

的完整视图(_user.html.erb)
<li>
  <%= gravatar_for user, size: 52 %>
  <%= link_to user.name, user %>
<%- if @user %>
  <%= @user.microposts.count %>
<%- else %>
  THIS IS THE ERROR, THERE IS NO USER ON @user
<%- end %>
 <% if current_user.admin? && !current_user?(user) %>
    | <%= link_to "delete", user, method: :delete, confirm: "You sure?" %>
  <% end %>
</li>

导致这是错误,@用户没有用户。这意味着在部分上,\ @user根据rorra的评论不存在,那么我在哪里解决这个问题?

class UsersController < ApplicationController
  before_filter :signed_in_user,
                only: [:index, :edit, :update, :destroy, :following, :followers]
  before_filter :correct_user,   only: [:edit, :update]
  before_filter :admin_user,     only: :destroy


  def index

    @users = User.paginate(page: params[:page])
  end


  def show
    @user = User.find(params[:id])
    @microposts = @user.microposts.paginate(page: params[:page])
  end



  def new
    @user = User.new
  end

  def create
    @user = User.new(params[:user])
    if @user.save
      sign_in @user
      flash[:success] = "Welcome to Sample App!"
      redirect_to root_url
    else
      render 'new'
    end
  end

  def edit
  end

  def update
    if @user.update_attributes(params[:user])
      sign_in @user
      flash[:success] = "Profile updated"
      redirect_to @user
    else
      render 'edit'
    end
  end

  def destroy
    User.find(params[:id]).destroy
    flash[:success] = "User destroyed"
    redirect_to users_path
  end


  private

    def correct_user
      @user = User.find(params[:id])
      redirect_to root_path unless current_user?(@user)
    end

    def admin_user
      redirect_to root_path unless current_user.admin?
    end
end

这是views \ users \ index.html.erb

<% provide(:title, 'Users') %>
<h1>Users</h1>

<%= will_paginate %>

<ul class="users">
  <%= render @users %>

</ul>

<%= will_paginate %>

这里是views \ users \ show.html.erb

<% provide(:title, @user.name) %>
<div class="row">
  <aside class="span4">
    <section>
      <h1>
        <%= gravatar_for @user %>
        <%= @user.name %>
      </h1>
    </section>
    <section>
      <%= render 'shared/stats' %>

    </section>
  <br>
  </aside>


  <div class="span10">
    <%= render 'follow_form' if signed_in? %>
    <% if @user.microposts.empty? %>
<h3>Microposts (<%= @user.microposts.count %>)</h3>
<% end %>
    <% if @user.microposts.any? %>
      <h3>Microposts (<%= @user.microposts.count %>)</h3>
      <ol class="microposts">
        <%= render @microposts %>
      </ol>

      <%= will_paginate @microposts %>
    <% end %>
  </div>
</div>

1 个答案:

答案 0 :(得分:0)

使用以下代码更新您的部分(\ views \ users \ _user.html.erb):

<%- if @user %>
  <%= @user.microposts.count %>
<%- else %>
  THIS IS THE ERROR, THERE IS NO USER ON @user
<%- end %>

你会得到最后一句:P

问题是部分上的@user是一个nil对象,而不是具有User对象

如果您从 show 操作中调用partial,那么您不应该有一个nil对象,因为如果@user为nil,它将在您的操作的第二行引发异常(并且它不会达到部分)。

现在,让新开发人员感到困惑的是,在部分内容中,您通常会传递一个对象,其名称是部分的名称,因此如果您的部分名称(如本例中)名为 _user ,并且您将默认对象传递给此部分,然后您将能够使用变量用户而不是实例变量 @user 来引用该对象

在您的视图中尝试此代码:

<%= user.microposts.count %>

为了使这项工作,您通常会发送像

这样的对象
<%= render partial: '/views/users/user', object: @my_user %>

甚至

<%= render @user %> 

将查找视图_user.html.erb

您通常使用这些部分来渲染集合,例如

<%= render partial: '/views/users/user', collection: @users %>

有关详细信息,请阅读Rails Guide about partials


部分看起来像这样:

    <li>
      <%= gravatar_for user, size: 52 %>
      <%= link_to user.name, user %>
      <%= user.microposts.count %>
      <% if current_user.admin? && !current_user?(user) %>
        | <%= link_to "delete", user, method: :delete, confirm: "You sure?" %>
      <% end %>
    </li>

使用

从index.html.erb调用partial的方式
<%= render @users %>

它非常好

你用什么宝石进行分页?我认为问题在于 paginate 会返回ActiveRecord关系,而不是每个用户的数组。

将您的控制器索引操作更新为:

@users = User.paginate(page: params[:page]).all