登录后current_user被认为是nil引发NoMethodError

时间:2017-07-24 13:42:19

标签: ruby-on-rails session-state

登录后,我收到一个动作控制器例外:

静态页面中的

NoMethodError #home
未定义的方法'email'代表nil:NilClass

以下current_user部分第12行的_comment.html.erb被视为零:

<li id="comment-<%= comment.id %>">
    <%= link_to gravatar_for(comment.user, size: 30), comment.user %>
    <span class="comment-content"><%= link_to comment.user.name, comment.user %>&nbsp;<%= comment.content %></span>
    <span class="timestamp">
        Posted <%= time_ago_in_words(comment.created_at) %> ago.
        <% if current_user?(comment.user) %>
            <%= link_to "delete", comment, method: :delete, remote: true %>
        <% end %>
    </span>
    <% if logged_in? && (current_user == comment.user || current_user = comment.micropost.user) %>
        <div class="reply-section">
            <%= link_to gravatar_for(current_user, size: 20), current_user %>
            <%= form_for(current_user.replies.build) do |f| %>
                <%= render 'shared/error_messages', object: f.object %>
                <div><%= f.hidden_field :comment_id, value: comment.id %></div>
                <div class="reply-box">
                    <%= f.text_area :content, rows: "1", class: "reply_area" %>
                </div>
                <%= f.submit "Reply", class: "btn btn-primary btn-xs" %>
            <% end %>
        </div>
    <% end %>
    <div class="replies-section">
        <% if comment.replies.any? %>
            <ol id="replies_comment-<%= comment.id %>">
                <% comment.replies.each do |reply| %>
                    <%= render reply %>
                <% end %>
            </ol>
        <% end %>
    </div>
</li>

例外的电子邮件是gravatar_for定义中的电子邮件。
如果我删除了第12行,则引发的异常是未定义的方法'回复'为nil:NilClass ,即下一行中的current_user
上述部分作为<%= render comment %>插入微博部分。我试图直接在微博部分添加代码,但无论如何都会引发异常。

引发异常的代码属于回复功能:用户可以发布微博,对微博发表评论以及回复评论。

我不明白为什么current_user在登录后被视为零。
current_user在会话助手中定义如下:

def current_user
    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

条件if logged_in?上方的两行仅检查current_user不是nil,因为方法logged_in?定义为!current_user.nil?此外,current_user被调用在micropost partial中有很多次,插入注释partial,但rails会在那时开始引发异常。

2 个答案:

答案 0 :(得分:1)

在您的情况下:

<% if logged_in? && (current_user == comment.user || current_user = comment.micropost.user) %>

您正在分配current_user而不是检查导致问题的原因:

current_user = comment.micropost.user

应该{​​{1}}代替===为nil,分配给comment.micropost.user并且它会让您例外。

答案 1 :(得分:1)

您在此处有错误:

<% if logged_in? && (current_user == comment.user || current_user = comment.micropost.user) %>

您要将comment.micropost.user分配给current_user,而不是比较其值。

因此,当达到该点时,您会收到错误,因为current_user值设置为您在comment.micropost.user中的任何值,并且由于它不是有效的id,因此您获得nil 1}}来自current_user

要解决此问题,只需将=更改为==

即可
<% if logged_in? && (current_user == comment.user || current_user == comment.micropost.user) %>