【问题标题】:Rails Observers, Plugins and Migrations are in a race, who wins?Rails 观察者、插件和迁移正在竞争,谁赢了?
【发布时间】:2011-11-15 17:18:36
【问题描述】:

我们刚刚在 Rails 应用程序中添加了几个观察者。现在,当从头开始运行迁移时,我们收到一个错误,指出表不存在(呃,我们还没有迁移)。抛出该错误是因为正在加载模型中的插件,该插件要求提供 column_names。

我假设观察者导致模型被加载,因为当我们在 application.rb 中注释掉观察者行时,不会引发错误。

如何在不加载观察者和模型的情况下运行迁移?

如何以在运行迁移时不会引发错误的方式在插件中请求 column_names?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-plugins rails-migrations


    【解决方案1】:

    在您的模型中,您可以捕获运行迁移时生成的特定异常。

    【讨论】:

    • 我可能会在插件中捕捉到异常,但绝对不是模型。
    • 我不认为我理解得很好,“正在加载模型中的插件要求 column_names”是什么意思,在哪里调用 column_names 方法?顺便说一句,它是什么插件?
    • 我们编写了插件,它不公开。它所做的部分工作是检查包含它的模型是否具有特定列。
    • 好的,所以在插件中你可以在调用column_names之前检查表是否存在,比如ActiveRecord::Base.connection.tables.include?(table_name),你可以把它封装在一个table_exists中?插件中的方法。
    • 幽默table_exists?已经作为 ActiveRecord::Base 的一部分存在。问题不在于它是否存在。进行迁移时不应加载该插件。我试图避免检查,因为如果表或列不存在,我希望它大声失败。
    【解决方案2】:

    我还没有找到在运行时禁用观察者的好方法。这已经在Simple way of turning off observers during rake task? 中讨论过

    但是,我想您可以通过在迁移中重新定义麻烦的模型来从模型中“拔出”插件代码:

    class YourMigration < ActiveRecord::Migraation
      class YourModel < ActiveRecord::Base; end
    
      def self.up
        ...
      end
    
      def self.down
        ...
      end
    end
    

    【讨论】:

    • 返回并调整我的所有迁移可能不是一个好的方法,但感谢您提供指向另一个问题的链接。
    • 链接实际上为配置提供了这个很棒的修复:config.active_record.observers = :my_model_observer 除非 File.basename($0) == 'rake'
    • 这不是在运行时禁用观察者的方法,但是,是的,我没有意识到这可能是您的情况下的一个很好的解决方案。
    【解决方案3】:

    在 Rails 3 中,您可以通过确定 Rake 是否正在运行来跳过添加观察者:

    config.active_record.observers = :my_model_observer unless File.basename($0) == 'rake'
    

    这会关闭观察者,这意味着模型和插件不会被加载。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-04
      • 2012-02-15
      • 1970-01-01
      相关资源
      最近更新 更多