每次避免current_user命中db? Ruby on Rails

时间:2013-11-21 06:05:28

标签: ruby-on-rails ruby database cookies

我关注Ruby on Rails Tutorial。代码已经给出,

在会话助手中:

  def sign_in(user)
    remember_token= User.new_remember_token
    cookies.permanent[:remember_token]=remember_token #save the unencrypted token to browser cookies
    user.update_attribute(:remember_token, User.encrypt(remember_token))
    self.current_user= user
  end

  def current_user=(user)
    @current_user= user
  end

  def current_user
    encrypted_token=User.encrypt(cookies[:remember_token])
    @current_user ||=User.find_by(remember_token:encrypted_token)
  end

  def sign_in?
    !current_user.nil?
  end
导航器视图中的

<% if sign_in? %>
          <li><%= link_to "Profile",current_user %></li>
<% end %>

我的问题是:

  1. 每次访问者刷新导航器时是否会访问数据库?
  2. 我可以在视图中使用@current_user并将sign_in?函数更改为:
  3. 来减少数据库命中率
    def sign_in?
      if @current_user.nil?
        !current_user.nil?
      else
        false
      end
    end
    

    3.解决此问题的最佳做法是什么?

    提前致谢。

3 个答案:

答案 0 :(得分:2)

我认为您的解决方案很好,不需要修复。

我确实有两个建议/替代方案,如果您对当前情况不满意,可能需要探索一下( 但是我不建议您使用这些解决方案,我只是打算说明备选方案 ):

  1. 使用会话而非数据库。 HTTP是无状态的。然而,会议被发明为制作http 有状态。您可以使用会话,并存储对该的引用 当前的用户。然后,您可以检查会话中是否存在user_id,而不是每次都访问数据库。这当然会降低您的安全性。这取决于您的应用程序的性质,这是否应该为您所接受。
  2. 仅检查访问级别更改的凭据。这是一种更实用/松散的用户授权方法。 如果您发现在您的情况下可接受的安全性降级 ,则由您决定。 它的工作原理如下:例如,我们有一个带页面的简单网站。最低访问级别是读级别的,如果用户决定编辑页面,他会进入写级别。在这种方法中,访问级别的更改将是您再次进行完整身份验证检查的时刻。因此,并非每次都是,只有在您更改访问级别时才重新进行身份验证并重新授权用户。也许您还想随意确定是否要重新进行身份验证/重新授权,这样可以避免可预测性。

答案 1 :(得分:1)

没有“解决方案”。

HTTP服务器是无状态的。每个请求都是新的。实例变量仅存在于每个请求中,这意味着在下一个请求中它将不存在。

记住此用户“状态”的唯一方法是将一些数据保存到db并在每次请求时对其进行身份验证。

不用担心db,它们的目的是运行:)

答案 2 :(得分:0)

如果记录加载很简单,您可以使用second-level-cache来保存数据库请求。但是,由于您使用某种键查找用户,这将无效。

但是每次从数据库加载用户都应该没问题。这是Rails项目中的常见做法。