如何显示在线用户
我正在写一个简单的聊天,我需要在线列出用户。 我没有使用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