【问题标题】:Using a private method with Single Table Inheritance使用具有单表继承的私有方法
【发布时间】:2015-02-21 01:09:45
【问题描述】:

我正在开发一个 Rails 应用程序,其中有 2 种不同类型的用户(MasterClientUser 和 AccountManager)。我正在使用单表继承来区分用户。我有一个 update_last_seen_at 私有方法,需要在 AccountManager 和 MasterClientUser 上调用。我正在尝试将其放入用户模型中,但出现以下错误:

private method `update_last_seen_at' called for #<MasterClientUser:0x007fc650d2cad0>

从 HomeController 调用 update_last_seen_at 方法:

class HomeController < ApplicationController

  before_action :authenticate_user!, :save_users_access_time, only: [:index]

  def index
    @user = current_user
  end

  def save_users_access_time
    current_user.update_last_seen_at
  end

end

型号

class User < ActiveRecord::Base
end

class MasterClientUser < User

  private

  def update_last_seen_at
    self.update_attributes(last_seen_at: Time.now)
  end

end

class AccountManager < User
end

我也尝试将方法放入一个模块中,并将该模块包含在每个不同的用户类型中,但我得到了同样的错误。

有什么方法可以共享两种用户类型的方法并保持私有,而不必明确地将它们放入每个模型中?/有没有更好的策略来解决这个问题。

【问题讨论】:

  • 调用 update_last_seen_at 的代码在哪里?私有方法不能有明确的接收者。你能在没有明确接收者的情况下编写调用吗?
  • 只要把它放在User 中就可以在所有子类中访问。如果您收到此错误,则表示您正在调用此方法破坏对象隐私,因此我们需要查看调用该方法的代码行。
  • 已更新以显示调用 update_last_seen_at 方法的位置
  • 编辑后-如果要在控制器中调用模型上的方法,它不是私有方法。那你为什么要把它设为私有呢?

标签: ruby-on-rails ruby single-table-inheritance private-methods


【解决方案1】:
def save_users_access_time
  current_user.update_last_seen_at
end

你不能在它自己的用户类之外调用私有方法,这就是你遇到问题的原因,你可以将该方法更改为普通的公共方法

尽管如此,我实际上认为整个方法是不必要的,如果它要做的只是更新last_seen_at 字段,您可以考虑改用touch

def save_users_access_time
  current_user.touch(:last_seen_at)
end

【讨论】:

    【解决方案2】:

    在用户类中将方法定义为受保护的,这将让派生类使用它。我认为对方法类型的一个很好的(一般)解释是:What is the difference between Public, Private, Protected, and Nothing?,希望对您有所帮助。

    虽然 ruby​​ 只支持这个:

    Ruby 为您提供三个级别的可访问性:

    1. 每个人都可以调用公共方法 - 不强制执行访问控制。一个类的实例方法(它们不只属于一个对象;相反,类的每个实例都可以调用它们)默认是公共的;任何人都可以打电话给他们。初始化方法始终是私有的。
    2. 受保护的方法只能由定义类及其子类的对象调用。访问权限保留在家庭内部。但是,protected 的使用是有限的。
    3. 不能使用显式接收器调用私有方法 - 接收器始终是自身。这意味着私有方法只能在当前对象的上下文中被调用;你不能调用另一个对象的私有方法。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-19
    • 1970-01-01
    • 2014-11-24
    • 1970-01-01
    相关资源
    最近更新 更多