【问题标题】:How to show online users如何显示在线用户
【发布时间】:2016-04-04 08:06:41
【问题描述】:

我正在编写一个简单的聊天,我需要列出在线用户。我不使用devise 进行身份验证,有一个自定义的user 模型通过omniauth 进行身份验证。

user.rb

class User < ActiveRecord::Base
    has_many :messages, dependent: :delete_all
    class << self
        def from_omniauth(auth)
            provider = auth.provider
            uid = auth.uid
            info = auth.info.symbolize_keys!
            user = User.find_or_initialize_by(uid: uid, provider: provider)
            user.name = info.name
            user.avatar_url = info.image
            user.profile_url = info.urls.send(provider.capitalize.to_sym)
            user.save!
            user
        end
    end
end

application_controller.rb

def current_user
    @current_user ||= User.find_by(id: cookies[:user_id]) if cookies[:user_id]
end
helper_method :current_user

我试图这样做:添加到application_controller.rb show_online 方法:

def show_online
    @users = User.where(status: online)
end

helper_method :online_users

然后添加到视图中:

<%= online_users.each do |user| %>
<ul>
    <li><%= user.name %></li>
</ul>
<%end%>

但它会抛出异常ActionView::Template::Error (undefined method 'online_users' for #&lt;MessagesController:0x007f52d7f82740&gt;)

source code这里

编辑

我找到了here 对我来说最好的解决方案,但我完全不知道如何正确实现它:( 但这绝对是我需要的

【问题讨论】:

  • 可能 Users.find(:all, :conditions =&gt; ["status = ?", "online"]) 返回 nil 这就是原因。
  • 不要引用我的话,但我很确定你使用的这个 find 语法很久以前就被删除了。还提供适当的错误消息。它应该告诉你什么对象没有每个方法,这对调试很有帮助。
  • @2call-chaos 它返回ActionView::Template::Error (undefined method 'each' for nil:NilClass)
  • @AlexNikolaev94 这是因为 find 方法需要一个 ID 来查找一条记录(我猜你没有 ID :all)。请在此处查找文档guides.rubyonrails.org/active_record_querying.html
  • 你检查我的帖子你使用我提到的可能性吗@AlexNikolaev94

标签: ruby-on-rails ruby-on-rails-4


【解决方案1】:

应该是&lt;% %&gt; 而不是&lt;%= %&gt;

<% @users.each do |user| %>
    <ul>
    <li><%= user.name %></li>
</ul>
<% end%>

其次

但您还需要检查 @users 是否为 nil,因此 nil.each 每个都会​​抛出该错误 ActionView::Template::Error (undefined method 'each' for nil:NilClass)

它看起来像

<% if @users %>
 <% @users.each do |user| %>
  <ul>
    <li><%= user.name %></li>
  </ul>
 <% end%>
<% end %>

或在控制器中

def show_online
  @users = User.where(status: 'Online')
end

<% @users.each do |user| %>
<ul>
    <li><%= user.try(:name) %></li>
</ul>
<%end%>

我为什么选择where not find all

【讨论】:

  • 这将停止打印数组,但与错误无关。
  • 如果使用 User.where,则不需要 if 语句。如果没有人在线,它将返回空数组[]
  • @RajarshiDas 知道了,对于 user.name
【解决方案2】:

您的应用程序控制器代码错误:

class ApplicationController < ActionController::Base
  def show_online
    @users = User.where(status: 'online')
  end
  helper_method :online_users
end

应该是:

class ApplicationController < ActionController::Base
  def online_users
    @users ||= User.where(status: 'online')
  end
  helper_method :online_users
end

【讨论】:

  • 正确,但这是他问的那个。其他问题与异常无关。
【解决方案3】:

编辑:

您遇到的错误可以通过以下两种方式之一解决。
您可以使用辅助方法并从您的视图中调用它们,就像您想要做的那样。
或者,您可以完全避免使用它们,而只在加载视图时从当前正在使用的任何方法调用 show_online 方法。如果你要去show,它将是 show 方法,依此类推。

您自己的答案确实使用第一种方法正确修复了错误,但我推荐这种方式。

实施这些修复需要做些什么:

  • 在加载 new 时调用 show_online,以便视图可以访问 @users 变量。我们可以通过 before_action

  • 做到这一点
  • 在视图中,您有一个循环遍历online_users,但它应该遍历@users

  • 在视图中的同一个循环中,您有一个简单的语法错误。第一行以&lt;%= 开头,但应以&lt;% 开头,不带=。无论您以何种方式编写代码,都应该更改此设置。

所以所有的代码是:

application_controller.rb

#put this line at the top of the controller, just below the line ApplicationController:: .....
before_action :show_online, only: [:new]

def show_online
    @users = User.where(online: true)

视图文件

<% @users.each do |user| %>
  <ul>
      <li><%= user.name %></li>
  </ul>
<% end %>

为什么要用这种方法?

  • 一种获取在线用户的方法意味着逻辑只有一个地方
  • 将您的逻辑/代码放在一个地方意味着您永远不会重复自己,并且您知道在出现问题时该去哪里查看
  • 使用 before_action 意味着除非需要,否则不会进行调用
  • 如果您稍后添加需要获取在线用户列表的页面,您只需将这些页面添加到括号中的方法列表中:only: [:new]
  • 在将逻辑放置在视图中或控制器中进行选择时,正确的答案几乎总是控制器

【讨论】:

  • 谢谢!但我实际上没有正确获得show 方法 - current_user 方法必须嵌套在其中?
  • @AlexNikolaev94 您可以从加载视图的任何方法调用 show_online 方法,它不必是 show 方法。您的视图文件的名称是什么?这将告诉我们我们需要什么方法。
  • 我刚刚按照你说的做了 - &lt;% @users.each %&gt; 现在它返回给我 ActionView::Template::Error (undefined method 'each' for nil:NilClass)。正如我在回答中所说的那样,当我这样做时,没有错误,但在线用户并未显示在列表中。
  • 视图文件的名称是什么?
  • 现在有NoMethodError (undefined method 'show_online' for #&lt;MessagesController:0x007f21e4279a18&gt;)
【解决方案4】:

从错误消息看来,您的 @users 不是数组或 ActiveRecord::Relation

我会打印出视图上的@users 以进行调试。此外,find(:all, :conditions =&gt; ["status = ?", "online"]) 也不是最好的查询方式。

使用User.where(:status =&gt; "online")。参考——http://guides.rubyonrails.org/active_record_querying.html#conditions

【讨论】:

  • 仍然没有帮助:(
  • 那么你的调试结果是什么?同样的错误?如果@users 的班级呢?
  • 谢谢。几个错误: 1. 我想你的意思是@online_users 不是online_users。 2. 将@users = User.where(status: online) 更改为@online_users = User.where(status: "online")。另外,我建议你在视图上添加&lt;%= @online_users.class %&gt;,看看是什么类。
猜你喜欢
  • 2011-12-13
  • 1970-01-01
  • 2020-05-06
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
  • 1970-01-01
  • 2014-08-29
  • 2019-02-20
相关资源
最近更新 更多