0

更新:所有,感谢您的回复-这里有一些更重要的信息。

我正在使用 Neo4J 图形数据库作为后端、ROR 3 (MRI),以及通过 REST 访问的单个 Neo4J 数据库服务器。

如果您对 Neo4j 不太了解,使用多个数据库服务器(主/主)来处理数据需要 26,000 美元,这意味着我必须现在编写优化代码,而不是以后,或者拿出 26,000 美元......我'确定您可以猜到我要采用哪种方式。我通过休息而不是本地等方式使用它,因此性能很重要...

我有一个必须处理所有数据库工作的数据库服务器,是的,在这种情况下需要 1 毫秒,而其他一些查询最多需要 40 毫秒。所以不,我不想不必要地访问数据库,因为它只会增加不必要的工作。

考虑到瓶颈和高昂的成本,说“不要为优化或尚未解决的问题编写代码”可能很容易——事实上,除了身份验证部分,我已经完成了我需要做的事情,它确实没有t 申请。

我只是想知道,@current_user ||= 是否跨页面有效。答案是它在请求中有效,而不是跨页面或跨页面有效。是的,这是一个简单的问题,但有时他们必须在研发和先进的东西中被问到。因此,我的直觉是坚持使用会话来保存登录用户的 ID。

谢谢你的帮助!


我试图允许用户通过 cookie 或用户名和密码登录到我的网站。用户名/密码部分工作正常,但在引入 cookie 时出现问题....

我已经准备了很多“如何做”,包括: http ://ruby.railstutorial.org/chapters/sign-in-sign-out

我不想使用宝石、设计等。

问题:

我注意到来自页面的读取 current_user(应用程序控制器中的帮助程序)的请求会导致数据库读取,即使我使用的是 ||=..

我试过 @current_user ||= User.find by blah blah blah

它总是命中数据库。这不应该是这样吧?它应该击中一次然后就可以了,对吗?

但是在你提出任何教程之前——我已经看过很多教程了——这是我的问题..@current_user 是跨页面保存的,还是仅用于当前页面?上面的链接提到它只保存当前页面...

你看,我不想继续不必要地访问数据库以找出以前登录的同一个人。我可以使用会话变量来做到这一点。

我真的只是想检查一个 cookie,并且很乐意在那之后继续使用 session[:user_id] .. 出于性能原因,我不想继续访问数据库。

有什么帮助吗?

我的新代码在下面(在这种情况下,这也总是会命中数据库)。我删除了典型的 @current_user ||= find_by.. 因为它没用 - 它总是在访问数据库。

.. 我已经尝试过https://github.com/cliftonm/basic-authhttp://ruby.railstutorial.org/chapters/sign-in-sign-out等。

(ROR 3.2...)

class ApplicationController < ActionController::Base
  protect_from_forgery
  #before_filter :set_var

  helper_method :current_user

private



def current_user

         @current_user = User.find_by_id(session[:user_id]) #if session[:user_id]
         if (@current_user)
           return @current_user
         end


       @current_user =User.find_by_remember_token(cookies[:auth_token]) if cookies[:auth_token]
       if (@current_user)
         return @current_user
       end


 end
4

3 回答 3

4

User.find除非您加载了某种缓存扩展,否则将始终访问数据库。Rails.cache可以配置多种方式,但如果需要这种方式,最流行的是Memcached

除非您正在处理大规模的扩展问题,否则获取用户记录所需的时间应该少于 1 毫秒,因此几乎不值得大惊小怪。检查您log/development.log的各种查询的执行时间,并首先关注最慢的查询。

像这样的实例变量在请求期间持续@current_user存在。请记住,HTTP 协议是无状态的,每个请求都独立存在,并且传递状态的唯一方法是通过 cookie、像数据库这样的持久存储、像内存缓存这样的临时存储,或者通过发送的参数通过 GET 或 POST 请求本身。

如果您想跨页面保存某些内容,请将其添加到 中session,但要小心。您应该只保留字符串、数字或布尔值等内容。您不应该添加模型。此外,使用默认的 cookie 存储,您在会话中放入的每件事都会增加从该点开始向您的应用程序发出的所有session请求的开销,直到您将其从存储中删除。

在解决所有其他问题之前,不要为小事操心。业务逻辑第一,优化第二。

于 2013-05-15T19:03:52.487 回答
0

这些都不应该每次都抨击数据库。请告诉我。

     if (@current_user)
       @current_user
     else
       @current_user = User.find_by_id(session[:user_id])
     end

或者

     @current_user ||= User.find_by(id: session[:user_id])
于 2015-05-13T18:08:44.020 回答
-1

您是否尝试过使用 before_filter(而不是助手)仅加载 current_user 一次?然后,您将使用实例变量存储/访问它。

class ApplicationController < ActionController::Base
  before_filter :load_current_user

  def load_current_user
    @current_user = # your code goes here.
  end
end

编辑:

我的错。如何在 cookie 中存储服务器端加密的 current_user 记录,并将哈希和保存在会话中以供以后检查?

于 2013-05-15T19:10:53.300 回答