【问题标题】:Best best way to wrap/override the current_user method from the devise gem?从设计 gem 包装/覆盖 current_user 方法的最佳方法是什么?
【发布时间】:2014-07-21 06:02:06
【问题描述】:

一个常见的模式是在很多地方使用current_user,但是检查它是否被设置。

if current_user
  #your code
end

但不是每次您想使用current_user 时都注入一个 if 检查,如何where 可以将 current_user 方法包​​装在一个不同的方法中一次, 这样您就不必处理由于设计的默认 current_user 方法的 nil 值而导致的代码中断?

【问题讨论】:

  • 你需要自己创造的魔法方法。
  • 这是已知的。

标签: ruby-on-rails design-patterns devise


【解决方案1】:

current_user 方法被添加到 ApplicationController,然后我认为您可以在 ApplicationController 中覆盖它,执行以下操作:

# in application_controller.rb
alias_method :devise_current_user, :current_user
def current_user
  if ...#your validation
    devise_current_user # || User.new    # <-- or whatever other non-nil result
  end  
end

【讨论】:

  • 我尝试在助手中这样做。如果在这里定义它为什么不起作用?
  • 为什么应用程序控制器中定义的方法表现为通用可调用的助手,而不是动作?毕竟它是一个控制器。
  • 实际上,这种模式仍然无法处理其他没有价值的情况。你需要一个 else 语句....
  • 好吧,我只是简化了解决方案。但是,是的,你需要一个 else。那是您应该返回某种其他类型的用户(例如访问者用户或其他东西)的地方。但你明白了。
【解决方案2】:

创建一个自定义类,其中包含您在整个应用程序中尝试在current_user 上使用的方法是一种方法。

http://littlelines.com/blog/2013/06/22/how-to-guard-against-ruby-nil-errors/

【讨论】:

    【解决方案3】:

    如果您不想在使用 ruby​​ 时考虑 nil 值的可能性,那么您将逆流而上,并变得非常沮丧。我知道我也有类似的感受。写起来真的很烦:

    if current_user && current_user.attr == 'val'
    

    但随着时间的推移,我已经开发出一些方法来减少这种尴尬......

    --编辑以显示我为避免这种情况所做的一些事情--

    我经常做这些事情。这不一定是建议或最佳实践,但我发现它有时会使我的代码不那么冗长且更具可读性

    如果我期望一个数组,但该数组可能是 nil:

    my_array ||= []
    

    这样我可以安全地做需要数组的事情,通常是在范围内的不同地方需要这样做的时候。

    my_array.size
    

    而且不会有东西窒息。

    我可能会这样做

    car ||= Car.new
    

    然后我可以像对待任何汽车对象一样对待汽车。不过,我可能不会对 current_user 这样做。

    【讨论】:

    • 关心概述这些方法是什么?非常好奇。这是我自己对这个主题的初步探索,这似乎是一个非常优雅和干燥的模式。我很想听听其他人的意见。
    • 我会以此为经验,但我仍然会为自己从经验和逻辑上质疑和探索它。在哪些情况下,current_user 为 nil 总比没有好?到目前为止,每次我使用它时,它都会破坏我的应用程序,因为我通常在 current_user 的返回值上调用方法。使用这种非零返回方法和设计的默认 current_user 方法不是一个很好的方法吗?
    • 该方法可以按原样设计,因为它太假设实现其他重新运行值,例如来宾用户(根据设计者和应用程序的要求可能会有很大差异),或者是错误的。谁会说选择 nil 而不是其他值(例如 false)是有充分理由的?在您了解设计问题以及最常见和最合理使用的情况之前,它可能是任意选择的,而不是错误的或其他值。仅仅依靠“它是有原因的方式”的论点是不够的,而且一般来说是错误的信息,imo。 (例如 ruby​​ 与 C++)
    • 虽然现状论据在逻辑上并不严格,但在概率上是正确的。我明白你的意思了。我很想知道这些原因是什么。
    • 在红宝石文化中,一种带有 ? (例如 current_user?)会返回一个布尔值,而 current_user 会返回一个值,在某些情况下它是 nil。我建议您编写代码以检查是否有用户,然后在一个块中执行特定于用户的操作,以及在另一个块中没有登录用户时执行的操作。 Devise 的 current_user 方法不是当前“站点”用户,而是当前登录的用户。
    猜你喜欢
    • 2011-09-19
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 2011-06-25
    • 2010-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多