我有一個Rails引擎命名空間Manager
,它有一個Wine
模型(Manager::Wine
)。Rails使用嚴格命名空間在引擎內評估模型
裝載引擎的應用程序也有一個Wine
模型,它沒有命名空間,但繼承自Manager::Wine
(見下文)。我遇到的問題是,安裝的引擎有一個我想調用的方法來獲取應用程序控制器使用的實例;然而調用Wine.find_whatever
實際上返回Manager::Wine
而不是主應用程序的Wine
模型 - 因此Wine
中存在的某些方法無法訪問。
有沒有辦法指定一個類不應該在當前命名空間內解析?
例子:
1)在所述引擎,則調用Wine.find_whatever
返回Manager::Wine
(根據默認行爲)
2)在發動機,調用Wine.top_level.find_whatever
返回對象在Wine
代替Manager::Wine
。
應用的Wine
類:
class Wine < Manager::Wine
searchable do
text :full_name, default_boost: 2, stored: true
text :description, stored: true
text :category_name, stored: true
text :oak_status, stored: true
text :blend_status, stored: true
text :sweetness_description, stored: true
text :sweetness_descriptor, stored: true
text :body, stored: true
boolean :stocked, using: :stocked?, stored: true
boolean :available, using: :available?, stored: true
boolean :publish_on_website, stored: true
end
def full_name
args = args.merge({show_year: false}) if hide_year
super args
end
def available?
publish_on_website and publish_on_pos and super
end
def oak_status
oaked? ? "oaked" : "unoaked"
end
def blend_status
blend? ? 'blends' : ''
end
end
Engine的find_model
代碼(其經由super
在主應用程序調用):
def find_model(args={})
m = controller_name.classify
find_by_attribute = args[:find_by].to_sym rescue :id
with_attribute = args[:with] || params[:id]
render_error = args[:render_error]
render_error = true if render_error.nil?
obj = "@#{ m.downcase }#{ 's' if args[:as_collection] }"
e = "#{ obj } = #{ m }"
e << ".includes(#{ args[:includes] })" if args[:includes]
e << ".where('#{ find_by_attribute } = ?', \"#{ with_attribute.to_s.gsub('"', '\"') }\")"
e << ".select(#{ args[:selects] })" if args[:selects]
e << ".first" unless args[:as_collection]
eval e
eval "render_status(404) and return false if render_error and #{ obj }.#{ args[:as_collection] ? :empty : :nil }?"
true
end