如何显示在线用户

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

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 

然后添加到视图:

  

但它抛出exceptionActionView::Template::Error (undefined method 'online_users' for #)

源代码在这里

编辑

我在这里找到的最好的解决方案,但我完全没有得到如何正确实现它:(但这绝对是我需要的

它应该是<% %>而不是<%= %>

 <% @users.each do |user| %> 
  • <%= user.name %>
<% end%>

其次

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

所以看起来会像

 <% if @users %> <% @users.each do |user| %> 
  • <%= user.name %>
<% end%> <% end %>

或在控制器中

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

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

为什么我选择哪里找不到所有

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

 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 

编辑:

您获得的错误可以通过两种方式之一解决。
您可以使用辅助方法并从视图中调用它们,因为您似乎想要这样做。
或者,您可以完全避免使用它们,只需在加载视图时从当前正在使用的任何方法调用show_online方法。 如果你要参加这个show ,它将是show方法,依此类推。

您自己的答案使用第一种方法正确修复错误,但我建议这样做。

需要做些什么来实现这些修复:

  • 在加载new时调用show_online,以便视图可以访问@users变量。 我们可以用before_action做到这一点

  • 在视图中,您有一个遍历online_users的循环,但它应该迭代@users

  • 在视图中的同一个循环中,您有一个简单的语法错误。 第一行以<%=开头,但应以<%而不是=开头。 无论您编写代码的方式如何,都应该更改。

所以所有代码都是:

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| %> 
  • <%= user.name %>
<% end %>

为什么这个方法?

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

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

我会在视图上打印@users进行调试。 另外, find(:all, :conditions => ["status = ?", "online"])不是最好的查询方式。

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