I figured out a solution. Regular models inherit from ActiveRecord::Base, so I modified my find_model method to allow for an override.
e = "#{ obj } = #{ 'ActiveRecord::Base::' if args[:use_activerecord_base] }#{ m }"
Domanda
I have a Rails engine namespaced Manager
which has a Wine
model (Manager::Wine
).
The app that mounts the engine also has a Wine
model which isn't namespaced, but inherits from Manager::Wine
(see below). The problem I'm having is that the mounted engine has a find_model
method that I want to call to get the instance for the app's controller to utilize; however calls to Wine.find_whatever
actually return the Manager::Wine
instead of the main app's Wine
model - and thus certain methods that exist in Wine
aren't accessible.
Is there a way to specify that a class shouldn't be parsed within the current namespace?
examples:
1) Within the Engine, calls to Wine.find_whatever
returns Manager::Wine
(as per the default behaviour)
2) Within the Engine, calls to Wine.top_level.find_whatever
returns the object in Wine
instead of Manager::Wine
.
App's Wine
class:
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's find_model
code (which is called via super
in main app):
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
Soluzione
I figured out a solution. Regular models inherit from ActiveRecord::Base, so I modified my find_model method to allow for an override.
e = "#{ obj } = #{ 'ActiveRecord::Base::' if args[:use_activerecord_base] }#{ m }"