A lot of controllers tend to have similar functionality and repetitive methods with other controllers. In some cases, you can create a "base" controller and then create derived classes to avoid repetition. Other times, though, there is no logical "base" - it's just a shared set of behaviors with nothing else in common. And, unfortunately, Ruby doesn't support multiple inheritance. But it does have something BETTER than multiple-inheritance - mixins.
Mixins are popular in Rails applications, particularly in controllers and models. Rails mixins can often be recognized by their use of an "-able" suffix.
A mixin is a module that defines one or more methods. The module is not usable on it's own. It has to be "mixed-in" to a class, and it's methods are then added to that class.
Think about how you can use mixins in your Rhodes app. I'll bet you can eliminate a lot of repetition in your controllers and models.
Here's a tiny little mixin that provides a transition capability to a Rhodes controller:
module Transitionable
attr_accessor :transition, :reload_on_transition
def initialize
@transition = :none
@reload_on_transition = true
end
def transition
WebView.execute_js( "$.mobile.changePage( '#{url_for(:action => :index)}',
{transition: '#{@transition}', reloadPage: #{@reload_on_transition}});")
end
end
I put this in my "helpers" directory. To use it in a controller, you need to add:
require 'helpers/transitionable'
at the top of your controller. Then, inside the class definition for your controller:
include Transitionable
The default transition is "none", meaning an instant page-flip. You can change the transition effect by setting @transition in your controller's initializer. If you do add an initializer, make sure to call super!
You can then use the "callback" form of action to call the transition method on the controller. For example, from the native toolbar:
def create_toolbar
@@toolbar = [
{ :action => :back },
{ :action => 'callback:/app/Message/transition', :label => 'Msg' },
{ :action => :separator },
{ :action => 'callback:/app/Settings/transition', :icon => '/public/images/gears.png'}
]
end
Even for something as tiny as transitionable, a mixin beats copy-and-paste hands down for maintainability! For example, want to change the default transition? Now you can just change it in one place.