I’ve been refactoring my models and controllers in an effort to remove code duplication, and so far it seems to be all peachy creamy. Currently I’ve got a bit of code that is common to two of my controllers, like so:
def process_filters # Filter hash we're going to pass to the model filter_to_use = {} # To process filters, we first query the model to find out what filters # we should be looking for, as the model knows what we can filter. Iso.available_filters.each do |filter| # We should have our array with our filter listing. # Check the purchase order model for a description filter_name = filter[0][:filter_name] # Filters are stored in a session variable, this way filters survive # page reloads, etc. First thing we do, is set the session if new filters # have been set for the filter. session_name = session_filter_name( filter_name ) if params[session_name] if params[session_name] == 'All' session[session_name] = nil else session[session_name] = params[session_name] filter_to_use[filter_name] = params[session_name] end elsif session[session_name] # If params aren't read, we still need to filter based off the users # session filter_to_use[filter_name] = session[session_name] end end # Just using this variable for now until I can refactor the helper code # so that this is passed in. @current_filter_values = filter_to_use filter_to_use[:page] = @current_page @isos = Iso.find_filtered( filter_to_use ) if @isos.out_of_bounds? filter_to_use[:page] = session[:previous_page] = @current_page = 1 @isos = Iso.find_filtered( filter_to_use ) end end
Now this code is exactly the same as code in another controller, except for the model reference (in this case Iso). Is there someway I can make that model reference dynamic?
Basically I’ld like to replace the Iso references (including the @iso variable) to something based off controller.controller_name or similar.
You can move this code into module, mixin this module in all controllers you need and use self.class variable inside module to figure out concrete controller name. With this name you can use standard string functions (e.g. capitalize) and Kernel.const_get function to get classes by their names.