我們正在基于一些環境變數動態加載代碼,效果非常好。
像這樣的東西:
# User class
class User
include DynamicConcern
end
module DynamicConcern
extend ActiveSupport::Concern
included do
if "Custom::#{ENV["CUSTOMER_NAME"].camelize}::#{self.name}Concern".safe_constantize
include "Custom::#{ENV["CUSTOMER_NAME"].camelize}::#{self.name}Concern".constantize
end
end
end
# custom code
module Custom::Custom123::UserConcern
extend ActiveSupport::Concern
included do
...
end
end
多年來我們一直在使用它,它在模型中運行得非常好。幾天前,我們嘗試對控制器使用相同的方法,但意識到這種方法不適用于繼承,其中父類繼承了關注點以及繼承的類:
class ApplicationController < ActionController::Base
# this gets loaded and includes the right dynamic module
include DynamicConcern
end
class ShopController < ApplicationController
# this is NOT getting loaded again and skipped,
# since it has been loaded already in the parent controller
include DynamicConcern
end
有沒有辦法告訴rails它應該第二次包含/評估關注點,因為第二次它會有另一個包含另一個模塊的類名?
我不是在尋找其他解決方案,因為我們的很多代碼都是基于這種方法的,我認為可以在不重寫所有內容的情況下解決這個問題。
謝謝!
uj5u.com熱心網友回復:
您只是嘗試根據類名動態包含模塊。
不需要關注,但它可以是一個普通的類,并且包含操作可以是一個普通的方法。每次你想呼叫它時,只要像其他任何方法一樣呼叫它。
因為您已經ActiveSupport::Concern以某種include方式撰寫了代碼。我想即使我不能保證以下重構可能會起作用。這個想法很簡單:
- 只需使其成為以目標類為引數的普通方法即可。您可以包含它(它會自動呼叫掛鉤)
dynamic_include。included - 如果模塊已經包含在祖先層次結構鏈中,只需呼叫
dynamic_include將立即呼叫該方法并進行動態包含。
請試一試,讓我知道它是否適用于您的場景。
module DynamicConcern
extend ActiveSupport::Concern
included do
def self.dynamic_include(klass)
if "Custom::#{ENV["CUSTOMER_NAME"].camelize}::#{klass.name}Concern".safe_constantize
klass.include "Custom::#{ENV["CUSTOMER_NAME"].camelize}::#{klass.name}Concern".constantize
end
end
dynamic_include(self)
end
end
class ApplicationController < ActionController::Base
# this gets loaded and includes the right dynamic module
include DynamicConcern
end
class ShopController < ApplicationController
# this is NOT getting loaded again and skipped,
# since it has been loaded already in the parent controller
dynamic_include(self)
end
uj5u.com熱心網友回復:
實際上,Rails 的一個特性是同一個模塊不會被多次加載。
我們開始使用普通的 ruby?? 模塊包含鉤子,它作業得很好!
module CustomConcern
def self.included(base)
custom_class_lookup_paths = [
"#{HOSTNAME.camelize}::Models::#{base.name}PrependConcern",
"#{HOSTNAME.camelize}::Controllers::#{base.name}PrependConcern"
].map{|class_string| class_string.safe_constantize }.compact
custom_class_lookup_paths.each do |class_string|
base.send :include, class_string
end
end
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/523030.html
下一篇:展開具有可變長度的多個陣列列
