如何向在线用户展示

时间:2016-04-04 08:06:42

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

我正在写一个简单的聊天,我需要在线列出用户。我不会使用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 #<MessagesController:0x007f52d7f82740>)

source code此处

修改

对我来说最好的解决方案我发现here,但我完全没有弄清楚如何正确实现它:(但这绝对是我需要的

4 个答案:

答案 0 :(得分:0)

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

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

其次

但您还需要检查@users是否为零,所以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

答案 1 :(得分:0)

编辑:

您获得的错误可以通过以下两种方式之一解决。
您可以使用辅助方法并从您的视图中调用它们,因为您似乎想要这样做 或者,您可以完全避免使用它们,只需在加载视图时从当前正在使用的任何方法调用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| %>
  <ul>
      <li><%= user.name %></li>
  </ul>
<% end %>

为什么选择这种方法?

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

答案 2 :(得分:0)

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

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

应该是:

{{1}}

答案 3 :(得分:-1)

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

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

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