【问题标题】:Rails 3 - Extending a model that exists in a gem or pluginRails 3 - 扩展存在于 gem 或插件中的模型
【发布时间】:2011-11-30 17:41:14
【问题描述】:

在 RefineryCMS gem 中有一个页面模型,用于从 CMS 中提取信息。该模型未在您当前的应用程序中定义,因此您无法修改其代码(除非您跳入 gem 代码)。

有没有一种方法可以修改现有模型中的方法,而不必在每次加载页面时都应用更改?这是我尝试过的:

  1. Model.class_eval

  2. Model.send :include, MixinThatHasNewMethods

我还尝试使用更新的方法创建一个新类,并希望这会更新现有的类。

有什么想法吗?

【问题讨论】:

    标签: ruby-on-rails ruby model-view-controller content-management-system


    【解决方案1】:

    如果我正确理解你的问题,你可以这样做。

    您可以按如下方式覆盖模型。假设您有以下课程:

    class User
     def name user_name
      p "my name is #{user_name}"
     end
    
     def age my_age
       p "age - #{my_age}"
     end
    
    end
    

    那么你可以通过以下方式调用这个类:

    user = User.new
    user.name "sameera"
    user.age 30
    

    你会得到输出:

    "my name is sameera"
    "age - 30"
    

    然后假设您只想更改“name”方法的行为,您可以重新创建用户类并仅添加该方法,如下所示:

    class User
     def name user_name
       p "my modified name #{user_name}"
     end 
    end
    

    您仍然可以按如下方式调用这两种方法:

    user = User.new
    user.name "sameera"
    user.age 30
    

    但这一次,你的输出将是:

    "my modified name sameera"
    "age - 30"
    

    我想你明白我的意思了,希望这会有所帮助。

    **注意:确保在加载原始 User 类之前调用​​修改后的“User”类。

    【讨论】:

      【解决方案2】:

      Ruby 允许开发人员随时“更新”任何对象。

      这意味着在 RefineryCMS 加载 Model 之后,您可以重新打开该类并对其进行更新:

      class Model
          def new_method(value)
              ...
          end
      
          def existing_method(*args)
              ...
              super  # refer to the ovewriten method
          end
      end
      

      在您的情况下,RafineryCMS 是一个 RoR 应用程序,这意味着在加载服务器时,首先为 rails 框架加载 ruby​​ 代码,然后为 RafineryCMS gem/插件加载,最后为您的自定义库(例如:lib 文件夹)加载。

      这里重点是代码的加载顺序,修改要在正版类代码之后加载。

      这是在您的库或初始化程序中(不是一个很好的地方,但它可以工作)您应该将您的自定义方法放在 Model 类中。

      编辑:我再次阅读您的问题,我不得不提一下,您错了,您实际上可以从 gem 或插件更改一个类。 ruby 加载同一范围内的每个对象,并且所有对象都可以被覆盖。

      在开发环境中,RoR 会在每次请求时重新加载所有类(除非 cache_classes = false)。在第一次请求之后,gem 可能会重新加载并且您的更改会丢失。请注意在每次请求后重新加载您的库(仅在开发环境中)

      PS:include & class_eval 也可以,重要的是覆盖了之前加载的类

      【讨论】:

        猜你喜欢
        • 2013-06-17
        • 2011-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-30
        • 2013-07-27
        • 1970-01-01
        相关资源
        最近更新 更多