【问题标题】:Undefined method `user' - Extending the Rails Tutorial未定义的方法 `user' - 扩展 Rails 教程
【发布时间】:2015-08-01 20:13:50
【问题描述】:

我正在开发一个待办事项列表应用程序,我所做的一切都是从第 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) %>

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 和private 下的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

【问题讨论】:

  • 此变量 @todo_list 为零,而您正在尝试执行 @todo_list.user 导致此错误 undefined method user for nil:NilClass 以及为什么 @todo_list 在家庭操作中为零。你没有在@todo_list中设置任何东西
  • 这行不是在做什么吗?...@todo_lists = @user.todo_lists.paginate(page: params[:page])
  • 所以@todo_lists = @user.todo_lists.paginate(page: params[:page])这一行将用户的待办事项列表设置在@todo_lists对象中,这是一个数组。这条线&lt;% if logged_in? &amp;&amp; current_user?(@todo_list.user) %&gt; 试图从@todo_list 获取用户,你看到s 丢失了。其次,您无法从 @todo_lists 数组中找到用户
  • 那么我将如何找到用户?那是我想不通的地方
  • @user 和当前用户有什么区别。其次,你能分享一下这个current_user?方法的代码吗?

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


【解决方案1】:

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

  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 来解决此问题 - 这应该添加必要的方法。

顺便说一句,我对您如何使用 current_user? 方法持怀疑态度。看起来你第一次调用它时,传入了@todo_list 对象......即使它定义正确,你怎么能期望 TodoList 对象成为当前用户?你为什么还要用那个对象调用那个方法?

【讨论】:

  • 我刚注意到有人投反对票,想评论原因或我本可以说/做些什么来更有帮助?谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-22
  • 1970-01-01
  • 2012-01-19
  • 2020-08-27
相关资源
最近更新 更多