Rails STI,回调以及公共与私有

时间:2015-06-09 20:02:04

标签: ruby-on-rails

我在Rails STI设置的父类中定义了一个回调和方法。

class Parent < ActiveRecord::Base
  before_save :populate_name

  # implicitly public
  def populate_name
    self.name = "foobar"
  end

class Child < Parent
end

当我像这样制作populate_name privateprotected时:

class Parent < ActiveRecord::Base
  before_save :populate_name

  private
  def populate_name
    self.name = "foobar"
  end

class Child < Parent
end

然后我收到此错误:

NameError - undefined local variable or method `populate_name' for #<Child:0x007ff901eace30>:
  activemodel (3.2.16) lib/active_model/attribute_methods.rb:407:in `method_missing'
  activerecord (3.2.16) lib/active_record/attribute_methods.rb:149:in `method_missing'
  activesupport (3.2.16) lib/active_support/callbacks.rb:407:in `_run__3119425560225797910__save__1411052685854526397__callbacks'
  activesupport (3.2.16) lib/active_support/callbacks.rb:405:in `__run_callback'
  activesupport (3.2.16) lib/active_support/callbacks.rb:385:in `_run_save_callbacks'
  activesupport (3.2.16) lib/active_support/callbacks.rb:81:in `run_callbacks'
  activerecord (3.2.16) lib/active_record/callbacks.rb:264:in `create_or_update'
  activerecord (3.2.16) lib/active_record/persistence.rb:84:in `save'
  activerecord (3.2.16) lib/active_record/validations.rb:50:in `save'
  activerecord (3.2.16) lib/active_record/attribute_methods/dirty.rb:22:in `save'
  activerecord (3.2.16) lib/active_record/transactions.rb:259:in `block (2 levels) in save'
  activerecord (3.2.16) lib/active_record/transactions.rb:313:in `block in with_transaction_returning_status'
  activerecord (3.2.16) lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
  activerecord (3.2.16) lib/active_record/transactions.rb:208:in `transaction'
  activerecord (3.2.16) lib/active_record/transactions.rb:311:in `with_transaction_returning_status'
  activerecord (3.2.16) lib/active_record/transactions.rb:259:in `block in save'
  activerecord (3.2.16) lib/active_record/transactions.rb:270:in `rollback_active_record_state!'
  activerecord (3.2.16) lib/active_record/transactions.rb:258:in `save'
  app/controllers/child_controller.rb:135:in `create_or_update'

回调需要public吗?

2 个答案:

答案 0 :(得分:1)

儿童无法访问私人方法。受保护的方法可以。孩子无法使用私人方法。

When should we consider using private or protected?

答案 1 :(得分:0)

保持这个问题以防万一有人用谷歌搜索这个问题(这是一个肥胖的手指)。

在模块结束之前,我意外地将私有部分放在课程结束之后。在最后一个结束之前,很容易抛出私有的,然后私有的方法,但是如果有嵌套的话,真的需要小心!

所以是的

  1. 将回调设为私人
  2. 如果您没有在Google查询中看到某些简单的内容,那么您必须有点胖的东西
  3. module Foo
      class Parent < ActiveRecord::Base
        before_save :populate_name
      end
    
      private
    
      def populate_name
        self.name = "foobar"
      end
    end
    
    class Child < Parent
    end
    

    然后我收到此错误:

    NameError - undefined local variable or method `populate_name' for #<Child:0x007ff901eace30>:
      activemodel (3.2.16) lib/active_model/attribute_methods.rb:407:in `method_missing'
      activerecord (3.2.16) lib/active_record/attribute_methods.rb:149:in `method_missing'
      activesupport (3.2.16) lib/active_support/callbacks.rb:407:in `_run__3119425560225797910__save__1411052685854526397__callbacks'
      activesupport (3.2.16) lib/active_support/callbacks.rb:405:in `__run_callback'
      activesupport (3.2.16) lib/active_support/callbacks.rb:385:in `_run_save_callbacks'
      activesupport (3.2.16) lib/active_support/callbacks.rb:81:in `run_callbacks'
      activerecord (3.2.16) lib/active_record/callbacks.rb:264:in `create_or_update'
      activerecord (3.2.16) lib/active_record/persistence.rb:84:in `save'
      activerecord (3.2.16) lib/active_record/validations.rb:50:in `save'
      activerecord (3.2.16) lib/active_record/attribute_methods/dirty.rb:22:in `save'
      activerecord (3.2.16) lib/active_record/transactions.rb:259:in `block (2 levels) in save'
      activerecord (3.2.16) lib/active_record/transactions.rb:313:in `block in with_transaction_returning_status'
      activerecord (3.2.16) lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
      activerecord (3.2.16) lib/active_record/transactions.rb:208:in `transaction'
      activerecord (3.2.16) lib/active_record/transactions.rb:311:in `with_transaction_returning_status'
      activerecord (3.2.16) lib/active_record/transactions.rb:259:in `block in save'
      activerecord (3.2.16) lib/active_record/transactions.rb:270:in `rollback_active_record_state!'
      activerecord (3.2.16) lib/active_record/transactions.rb:258:in `save'
      app/controllers/child_controller.rb:135:in `create_or_update'