【问题标题】:access control tripping me up访问控制绊倒我
【发布时间】:2011-12-28 22:42:56
【问题描述】:

好的,我正处于我的红宝石职业生涯的那个时候,这应该会让我绊倒。

我有一个名为 distribution.rb 的模型,其中我有以下 protected 方法:

  def update_email_sent_on_date
    if self.send_to_changed?
      self.date_email_delivered = DateTime.now
    end
  end

然后我从我的控制器调用这个方法:

 distribution.update_email_sent_on_date

但是,我收到了这个错误:

NoMethodError (protected method `update_email_sent_on_date' called for #<EmailDistribution:0x131a1be90>):

distribution 对象确实是一个 EmailDistribution(定义方法的分发的子类)。我认为这会奏效。无论如何,我也尝试将方法移动到子类EmailDistribution,但没有运气。同样的错误信息。

我还想退一步说,我总体上要做的是存储更新分布模型中另一个字段的时间戳。如果有更简单的方法,请赐教。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 rails-activerecord


    【解决方案1】:

    我认为你被绊倒了,因为你在实际需要 private 声明时使用了 protected 声明。

    The protected term in ruby acts differently in other conventional languages.

    在 Ruby 中,私有可见性在 Java 中是受保护的。 Ruby 中的私有方法可以从子级访问。这是一个明智的设计,因为在 Java 中,当方法是私有的时,它使得它对子类毫无用处:制定一条规则,所有方法都应该默认“受保护”,而不是私有的。然而,你不能在 Ruby 中拥有真正的私有方法。你不能完全隐藏一个方法。

    受保护和私有之间的区别是微妙的。如果一个方法是受保护的,它可以被定义类或其子类的任何实例调用。如果一个方法是私有的,它只能在调用对象的上下文中被调用——永远不可能直接访问另一个对象实例的私有方法,即使该对象与调用者属于同一个类。对于受保护的方法,它们可以从同一个类(或子类)的对象中访问。

    恕我直言,这是一个稍微清晰的解释,来自Eloquent Ruby by Russ Olsen一书:

    请注意,在 Ruby 中,私有方法可以从子类中调用。想一想:从子类调用超类方法不需要显式对象引用。

    受保护方法的规则更宽松,也更复杂一点:类的任何实例都可以在该类的任何其他实例上调用受保护的方法。

    最后,值得注意的是,在 ruby​​ 中,您始终可以调用私有或受保护方法,无论它们是否可以通过使用 send 方法访问。因此,如果您处于紧要关头,只是需要工作,您可以这样称呼它,然后再担心private/protected 声明:

    distribution.send(:update_email_sent_on_date)
    

    Read this for more a better explanation..

    【讨论】:

    • 很高兴能提供帮助,伙计。当我第一次开始在 Ruby 中使用继承时,我对 Ruby 如何处理 privateprotected 有点困惑,因为它处理这些术语的方式与我的背景所使用的传统语言不同。我假设你在同一条船。
    • 没错。在 Java 和 Python 之间,ruby 的差异足以让人感到困惑。
    猜你喜欢
    • 2011-01-31
    • 2013-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多