代码之家  ›  专栏  ›  技术社区  ›  Paul Alexander

从外部gem扩充模型

  •  6
  • Paul Alexander  · 技术社区  · 15 年前

    refinerycms 在我们的网站上让技术人员更新内容较少。在gem中,它们有一个页面类,映射站点上的每个顶级页面。我想在这个页面类中使用acts_作为可标记的gem。现在我可以将acts_as_taggle声明直接添加到page.rb文件中,但是之后我必须维护一个单独的git repo来跟踪我的版本和官方版本之间的差异。

    lib/页面扩展.rb:

    module Pants
      module Extensions
    
        module Page
          module ClassMethods
            def add_taggable
              acts_as_taggable
            end
          end
    
          def self.included(base)
            base.extend(ClassMethods).add_taggable
          end
    
        end
    
      end
    end
    

    配置/初始化器/pants.rb

    require 'page_extensions'
    
    Page.send :include, Pants::Extensions::Page
    

    app/views/layouts/application.html.erb

    ...
    Tags: <%= @page.tag_list %>
    

    第一次从服务器请求页面时,它会正确输出页面上的所有标记。但是,如果我点击刷新,我会得到一个 NoMethodError 表示标记列表未定义。

    1 回复  |  直到 14 年前
        1
  •  14
  •   parndt    14 年前

    您需要将模块评估代码放入 config.to_prepare do config/application.rb 或者创造一个引擎。代码是相同的,除了它每次运行站点时都执行,而不仅仅是第一次(尤其适用于开发模式)和仅在初始化过程(也称为需要文件)之前执行的代码 config.before_initialize do 封锁。

    原因是 config.to_prepare 很重要的一点是,在开发模式下,每个请求都会重新加载代码,但初始化器通常不会 Page ,它将只运行模块评估一次,但将重新加载每个请求。 准备配置

    config/application.rb方法

    class Application < Rails::Application
      # ... other stuff ...
    
      config.before_initialize do
        require 'page_extensions'
      end
    
      config.to_prepare do
        Page.send :include, Pants::Extensions::Page
      end
    end
    

    如果不想修改 配置/应用程序.rb 然后你可以,在炼油厂CMS中,创建 vendor/engines/add_page_extensions/lib/add_page_extensions.rb

    require 'refinery'
    
    module Refinery
      module AddPageExtensions
        class Engine < Rails::Engine
    
          config.before_initialize do
            require 'page_extensions'
          end
    
          config.to_prepare do
            Page.send :include, Pants::Extensions::Page
          end
    
        end
      end
    end
    

    如果使用引擎方法,还需要创建 vendor/engines/add_page_extensions/add_page_extensions.gemspec

    Gem::Specification.new do |s|
      s.name = 'add_page_extensions'
      s.require_paths = %w(lib)
      s.version = 1.0
      s.files = Dir["lib/**/*"]
    end
    

    然后在你的 Gemfile 添加此行:

    gem 'add_page_extensions', :path => 'vendor/engines'
    

    如果你采用引擎方法,你可能会想把你所有的逻辑都放在引擎的 lib 目录包括 Pants::Extensions::Page 代码。

    希望这有帮助