未定义的方法`user' - 扩展Rails教程

时间:2015-08-01 20:13:51

标签: ruby-on-rails ruby-on-rails-4 railstutorial.org

我正在研究Todo List应用程序,我所做的一切都是从第10章开始,我一直在使用第11章的部分,我需要这么做。我已经完成了我正在尝试在网站的其他部分上做的事情,只有用户可以看到制作待办事项列表的按钮,并且正确的用户待办事项在个人资料页面上,但由于某种原因我不能似乎与静态页面控制器主页操作一样。基本上,它与主页上显示的正确用户待办事项列表完成了99%,具体取决于您是否已登录,如果您未登录,则会看到其他内容。

整个 home.html.erb

<% if logged_in? && current_user?(@todo_list.user) %>

<div class="container">
<div class="row">
    <% @todo_lists.each do |todo_list| %>
        <div class="col-md-8 col-md-offset-2">
            <div class="well">
            <p class="todo_list_title"><%= link_to todo_list.title,   todo_list %></p>
            <p class="todo_list_description"><%= todo_list.description %>
            | <%= link_to "Show", todo_list_path(todo_list) %> 
            | <%= link_to "Edit", edit_todo_list_path(todo_list) %> 
            | <%= link_to 'Delete', todo_list, method: :delete, data: { confirm: 'Are you sure?' } %>
            </p>
            </div>
        </div>

    <% end %>
    <div class="col-md-8 col-md-offset-2">
      <%= link_to "New Todo List", new_todo_list_path, 
                   class: "btn btn-lg btn-primary" %>
    </div>
</div>
</div>

<% else %>
<div class="center jumbotron">
    <h1>Todo List App</h1>

    <%= link_to "Sign up now!", signup_path, class: "btn btn-lg   btn-primary"  %>
</div>
<% end %>

static_pages_controller.rb

使用static_pages_controller这样的主动作

def home
    @todo_lists = TodoList.all
end

以下是home.html.erb与其提供的结果的组合

<% if logged_in? %> 

这显示了所有用户的待办事项列表

<% if logged_in? && current_user?(@todo_list) %>

这会捕获else语句

<% if logged_in? && current_user?(@todo_list.user) %>

未定义的方法`user'代表nil:NilClass

使用 static_pages_controller 这样

def home
@user = User.find(params[:id])
@todo_lists = TodoList.all
end

或者像这样...

class StaticPagesController < ApplicationController

  before_action :logged_in_user
  before_action :correct_user

def home
    @user = User.find(correct_user)
    @todo_lists = @user.todo_lists.paginate(page: params[:page])
end


private

    def logged_in_user
        unless logged_in?
            store_location
            flash[:danger] = "Please log in."
            redirect_to login_url
        end
    end

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

end

上述示例中的所有三个都给出了此错误

无法找到“id”=

的用户

看起来私有的logged_in_user和correct_user方法的任何组合都不起作用,我似乎总是遇到上述错误之一,当我的用户配置文件正常工作时,这有点令人沮丧正确的用户已登录。

我确定答案很简单,因为它似乎总是如此,但我看不到它

此致 肖恩

更新

# Returns true if the given user is the current user.
def current_user?(user)
    user == current_user
end

# Define the method current_user
def current_user
    # Returns the current logged-in user (if any).

    if (user_id = session[:user_id])
        @current_user ||= User.find_by(id: user_id)
    elsif (user_id = cookies.signed[:user_id])
        user = User.find_by(id: user_id)
        if user && user.authenticated?(:remember, cookies[:remember_token])
            log_in user
            @current_user = user
        end
    end
end

1 个答案:

答案 0 :(得分:0)

我们需要完整的错误消息(以及堆栈跟踪/文件和行标识符的前几行),以便为您提供更精确的答案。但根据你所分享的内容,我猜测其中有两件事是真的:

  1. 您的@todo_list对象为nil或未正确定义。检查控制器;我看到你定义了@todo_lists(注意复数),但是如果你没有定义@todo_list那么它将默认为nil,当然nil不知道方法.user所以你会收到错误。
  2. 如果您确定(并且可以证明)@todo_list确实已经定义并且是预期的TodoList对象,那么TodoList对象可能不知道.user方法。您可以通过进入Rails控制台,创建一个新的TodoList对象并尝试在其上调用.user来验证这一点;如果你在那里遇到错误,你肯定会在上面的视图模板中出错。在ActiveRecord中,您可能会通过告诉TodoList.rb它belongs_to :user来解决这个问题 - 这应该添加必要的方法。
  3. 顺便说一下,我对你如何使用current_user?方法持怀疑态度。它看起来像你第一次调用它,传入@todo_list对象...即使它被正确定义,你怎么能期望TodoList对象成为当前用户?为什么你甚至用该对象调用该方法?