簡體   English   中英

將主應用中的類委托給Rails引擎中的類

[英]Delegate class in main app to class in rails engine

我有一個隔離的Rails Engine: Admin

在該引擎中,我通過GUI創建Sites

在引擎中:

module Admin
  class Site < ActiveRecord::Base
  end
end

在主應用程序中,我從引擎的Site繼承,以便在根級別將其用作常量:

class Site < Admin::Site
end

我這樣做是因為在主應用程序的模型,控制器和測試中將Admin::Site耦合在一起感覺不對。 但是我猜想這種方法有一些弊端,我也可能會認為耦合是相同的。

我該如何以比繼承更好的方式委派這個?

要么

我應該重組代碼,或者將Site類放到主應用程序和引擎都可以使用的gem中嗎? 我真正想要的是引擎類的接口,以減少入口點,從而減少耦合。

旁注,我總共有3-4個此類駐留在引擎中,但在主應用程序中使用。

編輯:

也許我應該像這樣包裝它:

class Site 
  def initialize(args = {})
    @klass = Admin::Site.new(args)    
  end

  def method_missing(method_name, *args, &block)
    @klass.send(method_name, *args, &block)
  end
end

當然,那么我還可以縮小Site的界面,使其僅包含主應用程序中Admin::Site所需的內容。

我想到了兩種可能的解決方案,
1)ActiveSupport :: Conern
2)公開課

鑒於您已經在引擎中隔離了這3-4個模型/控制器,一種方法是利用ActiveSupport :: ConcernMainApp中明確包含引擎的功能。

此處的更多信息, ActiveSupport :: Concern上的Rails Docs

ActiveSupport ::關注示例:

# Rails Engine
module SomeEngine
  module SomeController

    extend ActiveSupprt::Concern

    included do
      before_filter :some_before_filter
    end

    # regular instance methods
    def index 
      ...
    end

    protected
    def some_before_filter
      ....
    end

  end
end    

# MainApp
class SomeController < BaseController
  include SomeEngine::SomeController

  # rest of MainApp logic
end

另一種常見的方法是在運行時重寫Ruby類方法(“開放類”) Spree通過在MainApp中為Engine模型/控制器類實現“裝飾器”模式來實現此目的。

更多信息在這里, Spree的Decorators的實現

“ #class_eval做”示例,

# in MainApp
SomeEngine::SomeController.class_eval do
  # logic added in the MainApp
end

我還將在RailsEngnes上查看有關RailsConf的演講,
http://confreaks.com/videos/863-railsconf2012-rails-engines-patterns

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM