2011-12-28 2 views
0

ОК, я в тот момент в моей рубиновой карьере, где это должно меня отключить.контроль доступа отключил меня

У меня есть модель под названием distribution.rb, где у меня есть follwoing защищенный метод:

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 действительно является распределением электронной почты (подкласс распределения, в котором определяется метод). I мысль это будет работать. В любом случае я также попытался переместить метод в подкласс EmailDistribution, но не повезло. Такое же сообщение об ошибке.

Я также хотел бы отступить и сказать, что то, что я пытаюсь сделать в целом, это сохранить временную метку, когда обновляется другое поле в модели распределения. Если есть более простой способ, пожалуйста, просветите меня.

ответ

1

Я думаю, что вы сработали, потому что используете объявление protected, когда вы действительно хотите объявление private.

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

In Ruby, private visibility is what protected was in Java. Private methods in Ruby are accessible from children. This is a sensible design, since in Java, when method was private, it rendered it useless for children classes: making it a rule, that all methods should be "protected" by default, and never private. However, you can't have truly private methods in Ruby; you can't completely hide a method.

The difference between protected and private is subtle. If a method is protected, it may be called by any instance of the defining class or its subclasses. If a method is private, it may be called only within the context of the calling object---it is never possible to access another object instance's private methods directly, even if the object is of the same class as the caller. For protected methods, they are accessible from objects of the same class (or children).

Это немного понятнее объяснение ИМХО, из книги Eloquent Ruby by Russ Olsen:

Note that in Ruby, private methods are callable from subclasses. Think about it: You don't need an explicit object reference to call a superclass method from a subclass.

The rules for protected methods are looser and a bit more complex: Any instance of a class can call a protected method on any other instance of the class.

Наконец, это хорошо отметить, что в рубине всегда можно назвать частные или защищенные методы независимо доступны ли они с помощью метода send. Так что если вы в крайнем случае, и просто нужно работать, вы могли бы назвать его просто так, а затем беспокоиться о private/protected деклараций позже:

distribution.send(:update_email_sent_on_date) 

Read this for more a better explanation..

+0

благодарит за помощь! – Ramy

+0

Рад помочь, приятель. Я немного смутился о том, как Ruby обрабатывает «private» и «protected», когда я начал работать с наследованием в Ruby, потому что он обрабатывает эти термины по-другому, чем обычные языки, на которых мой фон находится. Я предполагаю, что вы находитесь в такой же лодка. – Batkins

+0

Точно. Между Java и Python, Ruby просто достаточно разный, чтобы запутать. – Ramy

Смежные вопросы