Warning Older Docs! - You are viewing documentation for a previous released version of RhoMobile Suite.

Rhodes Application

App structure

The Rhodes application generator generates a basic application from the “rhodes app” option. It will generate subdirectories and controller and template files when specifying a model and actions. Please refer to the Rhodes generator documentation for more detailed information about the Rhodes directory structure.

Example Directory Structure

As an example, /sugar could be the root folder for an application that provides mobile access to SugarCRM. The app’s root directory will contain a few .erb files, depending on the app’s functionality. At the very least there will be an index.erb file that serves as the default landing page. This default landing page will typically have links to the controllers for some of the data models, and is not associated with any specific controller. In case the application needs a default landing page associated with a controller, it is recommended to create a model/controller/view folder and use an action on this controller as a default start path. To do that, edit the start_path property in the Configuration framework configuration file.

Model/View/Controller

By convention, files for each Model include a controller, a model class and view templates described below.

Controller

Developer may create any number of controller actions by simple defining new methods in the controller class. Each action associated with url and can be performed by calling that url from the View in the WebView control. WebView control is a Web Browser imbedded in the application UI.

For example, if you have Account Model your controller actions will be in account_controller.rb file. To defined action ‘list’ you will create method ‘list’ in the account_controller.rb file:

def list
    #implement required business logic here
    #...
    #return result to the browser
    render :action => :list
end  

From the View list action will be available as ‘Account/list’ url.

Each generated model controller has several actions to perform basic CRUD (create, read, update and delete) on the object. These actions are:

  • index – lists all objects
  • new – displays the editing form for creating a new object
  • create – actually creates the object
  • edit – edits an existing object
  • update – updates properties of the object
  • show – views the object
  • delete – deletes the object

Generated set of actions (and the associated URL paths) follows the Rails scaffolding pattern for creating CRUD actions for objects and the associated “map resources” convention for routing to those actions.

Model

To store data locally Rhodes uses Sqlite on iPhone, Android, and Windows Mobile. On Blackberry version up to 5.0 Rhodes uses Hsql. On version 5.0 and higher it is possible to use Sqlite or Hsql. To access and manipulate stored data you may use Rhom. Rhom is a mini ORM (object relational mapper) for Rhodes. It provides a high level way to make the local database easier to program to.

By convention, your model class is located in the model’s folder. For the model “UserBase” the file would be called “user_base.rb”

Example of added upper_name method to the model:

class UserBase
    include Rhom::PropertyBag
    #add model specific code here
    def upper_name
        self.name.upcase
    end
end

You may define PropertyBag model or FixedSchema models. In first case model object may have any number of attributes and developer may create them on the fly by assigning values to an attribute. Fixed schema is more rigid and attributes of such objects should be defined at compile time. But Fixed Schema objects will require significantly less space on the target device. See more details about Rhom here.

Views (Templates)

Each controller action usually associated with a View template. The .erb files mentioned above are the templates used for views. Rhodes follows the Rails convention for template naming.

  • index.erb – lists the data model objects
  • edit.erb – lets you edit the object
  • show.erb – shows the object’s attribute values
  • new.erb – creates a new object

These files are all created by the rhodes generator. Inside the template, any valid HTML, JavaScript, and Ruby can be used, with Ruby code enclosed in <% and %> tags. See more information about ERB here.

To send View to the browser, use render method in your controller. For example, to render list.erb, make following call in your controller:

render :action => :list 

Rhodes framework will load list.erb template, process it, and send resulted HTML to the browser.

AppApplication class

To coordinate application startup Rhodes framework introduced Application class. This class persistent all the time while app is running and across all requests to the controller actions. You can store session data here. To get an instance of the AppApplication object in your controller, use:

::Rho.get_app

AppAplication class defined in the application.rb file:

class AppApplication < Rho::RhoApplication
  def initialize
    # put initialization code here
  end
end

You may listen for activation/deactivation/upgrade events if you define following methods on AppApplication class.

Method on_ui_created will be invoked after application’s UI was created (usually on app start)

def on_ui_created
    # put your application UI creation code here
    # for example, create tab bar:
    # NativeBar.create(Rho::RhoApplication::TABBAR_TYPE, tabs)

    super # To navigate to start_path from rhoconfig.txt
end

Method on_ui_destroyed will be invoked when application’s UI was destroyed (usually on app exit)

def on_ui_destroyed
    # put your code here
    # example:
    # @forbid_ui_operations = true
end

On iPhone, on_ui_destroyed invoked when also when application goes to background, because if application killed in background by user (via multitasking UI) then no any events sended to application. So if you want save state of your application, you can do it in on_ui_destoyed, but keep in mind – is just save – do not process destroy of your UI in this method

Method on_activate_app will be invoked after application is activated.

def on_activate_app
    # put your application activation code here
end 

Method on_deactivate_app will be invoked before application goes to background.

def on_deactivate_app
    # Don't call any UI operations here, they'll be ignored
    # For example, WebView.refresh

    # to stop sync background thread call 
    # SyncEngine.stop_sync; SyncEngine.set_pollinterval(0)

    # To stop local web server when application switched to 
    # background return "stop_local_server"
    # return "stop_local_server" 
end

Method on_reinstall_config_update may be called after application was upgraded. If application bundle contain rhoconfig with properties modified locally on the phone conflicts is a hash name to array of conflicted values(old local value, new upgrade value). By default local values are kept in place but you may overwrite configuration with new values and any other steps required for your application upgrade.

def on_reinstall_config_update(conflicts)
    # puts "on_reinstall_config_update: #{conflicts}"
end

Relative order of callbacks and conditions where they occurs

Look to the scheme of application life cycle:

initialize          -> called when application start
on_ui_created       -> called when application's UI created
on_activate_app     -> called when application become foreground

Now application is live and visible on the screen. Assume now that user somehow switched to another application (for example, answering to incoming call) or explicitly send app to background.

on_deactivate_app   -> called when application switched to background

Now, on this stage, application can be activated again (in this case on_activate_app will be called) or system can destroy it’s UI to free some memory (in this case on_ui_destroyed will be called). Let’s look on case if app’s UI was destroyed but then we activated app again:

on_ui_destroyed     -> called when OS destroy app's UI
on_ui_created       -> called just after user request system activate
                       app (for example, tap app's icon on screen)
on_activate_app     -> called when app goes to foreground

Ok, now user choose to exit from app completely (either by selecting menu item “Close” or calling System.exit method somewhere in app code). Let’s look on callbacks chain in this case:

on_deactivate_app   -> at first, app will be deactivated (become
                       invisible on screen)
on_ui_destroyed     -> then, app's UI will be destroyed
Kernel.at_exit      -> all calls registered by calling of
                       Kernel.at_exit will be called as in usual Ruby.

That’s how it’s working. Important thing to understand is that on_activate_app callback always called after on_ui_created and on_deactivate_app always called before on_ui_destroyed

Application Helpers

Few helper methods defined as part of the Rhodes framework. There are just a few of them because Rhodes framework designed for mobile environment where size is still of some concern and we tried to keep framework as tight as possible.

Generated application comes with number of other helpers (see app/helpers folder). These helpers are not used by the framework internally and may be modified/deleted/extended at will.

link_to

Examples of how to use the link_to method:

link_to "Visit Other Site", "http://www.rhomobile.com/"
==> <a href="http://www.rhomobile.com/" >Visit Other Site</a>

link_to "Help", { :action => "help" }
==> <a href="/app/model/help" >Help</a>

link_to "Delete", { :action => "delete", :id => '{12}' }
==> <a href="/app/model/{12}/delete"  onclick="
    var f = document.createElement('form'); 
    f.style.display = 'none'; this.parentNode.appendChild(f); 
    f.method = 'POST'; f.action = this.href; f.submit(); 
    return false;">Delete</a>

link_to "Show", { :action => "show", :id => '{12}'},
"style=\"height:4px;width:7px;border-width:0px;\"" 
==> <a href="/app/model/{12}/show" 
    style="height:4px;width:7px;border-width:0px;">Show</a>

link_to "Delete", { :action => "delete", :id => '{12}' }, 
"class=\"delete_link\""
==> <a href="/app/model/{12}/delete" class="delete_link" 
    onclick="var f = document.createElement('form'); 
    f.style.display = 'none'; this.parentNode.appendChild(f); 
    f.method = 'POST'; f.action = this.href; f.submit();
    return false;\">Delete</a>"

link_to "Invite",:action => :invite, 
:query => {:name=>'John Smith','address'=>"http://john.smith.com"}
==> <a href="/app/model/invite?
    name=John%20Smith&address=http%3A%2F%2Fjohn.smith.com">
    Invite</a>

url_for

Examples of how to use the url_for method:

url_for '/some_url'
==> /some_url

When generating a new URL, missing values may be filled in from the current request’s parameters. For example, if the application name or model are not specified in the call parameters, they would be filled from the request.

url_for :action => :index
==> /app/model

url_for :action => :create
==> /app/model

url_for :action => :new
==> /app/model/new

url_for :action => :show, :id => '{12}'
==> /app/model/{12}/show

url_for :model => :another_model, 
:action => :show, :id => '{12}'
==> /app/another_model/{12}/show

url_for :controller => :another_controller, 
:action => :show, :id => '{12}'
==> /app/another_controller/{12}/show

url_for :application => :another_app, 
:model => :another_model, :action => :show, :id => '{12}'
==> /another_app/another_model/{12}/show

url_for :action => :create, :query => 
{:name => 'John Smith', 'address' => "http://john.smith.com"}
==> /app/model?name=John%20Smith&address=http%3A%2F%2Fjohn.smith.com

url_for :action => :show, :id => '{12}', :fragment => "an-anchor" 
==> /app/model/{12}/show#an-anchor

Error handlers(400,500)

Rhodes can display the following error pages: app\E400.erb and app\E500.erb

  • error 400 occurs when there’s a Rho::RecordNotFound exception (for example, when you search for a non-existent objectID)
  • error 500 occurs for any other unhanded exception

To get exception object use $! or Rho::RHO.current_exception

RhoSupport class

Rho::RhoSupport.url_encode(url)

Encode url replacing special characters to %XX

Rho::RhoSupport.url_decode(url)

Decode url replacing %XX to special characters

Per Platform Files

On a per platform basis, you can use alternative files for any given file in your ‘app’ or ‘public’ folder. To do this, make a second file with the platform in the name of the file.

For example, to replace these files on the Android platform:

    default.css
    index.erb

All you need to do is add the two files:

    default.android.css
    index.android.erb

Note that you must still have the base file present for it to be replaced on a platform.

Valid platform names are:

  • android
  • wm
  • bb
  • iphone
Back to Top