Oomoo

March 11, 2008

Variables Across The MVC

Filed under: MVC — oomoo @ 1:53 pm

Here are some notes about variables, scoping, etc.

Variables in Ruby/Rails are of your fairly standard variety (local, instance, public).  There is another type called “class” or “class instance” variables that get way too much attention for the amount they are used (or not used) in most apps.  If you are learning Ruby/Rails, just ignore Class Variables for now and don’t use them. 

As with most languages/frameworks, it’s the “visibility” of variables that is important.  This is especially true with web-based applications.  Ruby is based on MVC (Model/View/Controller) architecture (see http://betterexplained.com/articles/intermediate-rails-understanding-models-views-and-controllers/ for a good MVC overview)

In the diagram shown at the website referenced above, notice that the Browse interacts with the Controller, which gets data from the Model, then passes it back using the View.

Models, View, and Controllers are just classes.  Rails hides their complexity making them seem like magic, but they are just Ruby classes.

Models        are ActiveRecord classes 
Views         are ActionView classes 
Controllers  are ActionController classes

Controllers and Views have a special arrangement though, since both of them are part of ActionPack.  This means they actually share a codebase.  (see http://ap.rubyonrails.com/ for a thorough a picture and an explanation)

…snippet…  “Action Pack splits the response to a web request into a controller part (performing the logic) and a view part (rendering a template). This two-step approach is known as an action, which will normally create, read, update, or delete (CRUD for short) some sort of model part (often backed by a database) before choosing either to render a template or redirecting to another action.   Action Pack implements these actions as public methods on Action Controllers and uses Action Views to implement the template rendering.  Some of the features, are tied to ActiveRecord, but that doesn’t mean that Action Pack depends on Active Record. Action Pack is an independent package that can be used with any sort of backend.” 

What this means for you, is that instance variables defined in a Controller are visible to any View called by that controller. 

Local Variable

      current_time = Time.now 

      If defined in a Controller, it can NOT be seen from “any” View called by the Controller. 
 

Instance Variable

      @current_time = Time.now 

      Can be seen only from “this” instance of this class

      If defined in a Controller, it can be seen from “any” View called by the Controller. 
 

Class (instance) Variable

      @@current_time = Time.now 

      Can be seen and changed from “any” instance of this class (one variable shared across all instances)

      If defined in a Controller, it can be seen from “any” View called by the Controller. 
 

Public/Global Variable

      $current_time = Time.now 

      Can be seen and changed from “anywhere” 
 
 
 

An Example 
 

\app\controllers\application.rb

$current_time = Time.now     # Global Variable  (visible everywhere) 
 
 

Controller

class OrdersController < ApplicationController

  def index

    @orders = Tblorder.find_recent_orders   # Call Model Method “find_recent_orders” 

    @filter_scope_name = “Recent Orders”   # Set Instance Variable (visible by view) 

    render :action => ‘list’     # Show the View

  end

end 
 

Model

class Order < ActiveRecord::Base 

  @filter_recent_days  = 15     # Instance Variable (NOT visible by view because this is the Model) 

  def self.find_recent_orders

                                                      # “sql” is a local variable  (not visible anywhere else)

    sql = “SELECT * FROM orders where DATEDIFF(curdate(), ordDateOrderTaken) <= “ + @filter_recent_days.to_s

  

    find_by_sql(sql)

  end

end 
 

View

<!– Most of the HTML is in \app\views\layouts\orders.rhtml –> 

<% if @orders.length == 0 then%>

  <p> No Orders Exist.</p>

<% else %>

  <% if @filter_scope_name %>     # Using Instance Variable from Controller

    <caption><%= h @filter_scope_name %></caption>

    Current Time: <%= $current_time %>     # Using Global Variable from file application.rb

  <% else %>

    <caption>Order List</caption>

  <% end %>

<% end %> 

<% for order in @orders %>

  <%= link_to order.id, :action => ‘show’ %> <br />

  <%= order.ordCustPONum %> <br />

  <%= order.ordOEM %> <br />

  <%= order.ordDescription %> <br />

  <%= order.ordModelNum %> <br />

  <%= order.ordSerialNum %> <br />

  <%= order.ordFinalDisposition %> <br />

  <%= order.ordDateOrderTaken %> <br />

<% end %> 
 
 

A Note About Controller Methods

Even though your Controller Instance Variables will be visible to your View, your Controller Methods will not.  You can get around this by placing methods that need visibility to the View in your Controller Helper (app\helpers\orders_helper.rb based on our example above). 

Advertisements

1 Comment »

  1. Your article is pretty uesful to me and support me solve a massive issue. I appreciate you very much. But i have some dilemma of comprehend the last paragraph. Can you say some details for me?

    Comment by Office 2007 Ultimate Serial Key — November 26, 2010 @ 12:02 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: