我有一个名为distribution.rb
的模型,其中包含以下受保护的方法:
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
,但没有运气。相同的错误消息。
我还想退一步说我正在尝试做的总是存储更新分发模型中另一个字段的时间戳。如果有更简单的方法,请赐教。
答案 0 :(得分:1)
我认为你正在被绊倒,因为当你真正想要protected
声明时,你正在使用private
声明。
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)