ONLamp.com
oreilly.comSafari Books Online.Conferences.

advertisement


What Is Ruby on Rails
Pages: 1, 2, 3, 4, 5, 6, 7

Callbacks

As Active Record creates and destroys model objects and creates and updates them in the database, you can monitor these events in the object's life cycle using callbacks. You can use callbacks to handle complex business logic, modify data before Rails writes it to the database (or after Rails reads it from the database), or just about anything else you like.



For example, the save method that saves a model object's data to the database has eight callbacks defined:

  1. before_validation
  2. before_validation_on_create
  3. after_validation
  4. after_validation_on_create
  5. before_save
  6. before_create
  7. after_create
  8. after_save

This gives you fine-grained control over your model objects when you need it.

class CreditCard < ActiveRecord::Base
  # Strip everything but digits, so the user can specify "555 234 34" or
  # "5552-3434" or both will mean "55523434"
  def before_validation_on_create
    self.number = number.gsub(/[^0-9]/, "") if attribute_present?("number")
  end
end

class Subscription < ActiveRecord::Base
  before_create :record_signup

  private
    def record_signup
      self.signed_up_on = Date.today
    end
end

class Firm < ActiveRecord::Base
  # Destroys the associated clients and people when the firm is destroyed
  before_destroy { |record| Person.destroy_all "firm_id = #{record.id}" }
  before_destroy { |record| Client.destroy_all "client_of = #{record.id}" }
end

The ActiveRecord::Callbacks documentation covers callbacks.

Transactions

A transaction is necessary when you have multiple database operations that all must succeed before the data in the database can change. If any one of them fails, the data in database should not change. Use transaction blocks to ensure this.

transaction do
  david.withdrawal(100)
  mary.deposit(100)
end

The database-level transaction shown above will prevent the withdrawal from David's account if the deposit into Mary's account should fail. It will not, however, protect the david and mary objects from being modified. To do that, you must use object-level transactions.

Account.transaction(david, mary) do
  david.withdrawal(100)
  mary.deposit(100)
end

Any failure in this code will roll back the value of the objects as well as the database.

The ActiveRecords::Transactions documentation explains more.

Much, much more

There is a lot more to Active Record than I can cover here. To learn more, consult the Active Record API.

Action Pack

Action Pack implements both the view and controller part of Rails.

View templates

View templates specify the HTML to return in response to a browser request. View templates are rhtml files (HTML with embedded Ruby) that are very similar to ASP or JSP files. Text within <% %> is Ruby code to execute, and text within <%= %> is also Ruby code to execute and substitute the results back into the HTML.

<html>
  <head>
    <title>Invoices for <%= @name
%></title>
  </head>
  <body>
    <% render_partial "invoices_by_customer"
%>
  </body>
</html>

By default, Rails will try to find a template whose name matches the currently executing action. If, for example, Rails executes an edit action in your InvoiceController, then it will attempt to find and render the view template .../app/views/invoices/edit.rhtml.

You can also build up XML (or HTML) output programmatically in your controller action. This is useful, for example, for building RSS feeds or responding to XML-RPC requests. In the following example, xm is an XmlMarkup object.

xm.em("emphasized")  # => <em>emphasized</em>
xm.em { xmm.b("emp & bold") }   # => <em><b>emph & bold</b></em>
xm.a("A Link", "href"=>"http://onestepback.org") # => <a href="http://onestepback.org">A
Link</a>
xm.div { br }                   # => <div><br/></div>
xm.target("name"=>"compile", "option"=>"fast")
                                # => <target option="fast" name="compile"\>
                                # NOTE: order of attributes is not specified.

xm.instruct!                    # <?xml version="1.0" encoding="UTF-8"?>
xm.html {                       # <html>
  xm.head {                     #   <head>
   xm.title("History")          #     <title>History</title>
 }                              #   </head>
  xm.body {                     #   <body>
    xm.comment!  "HI"           #     <!-- HI -->
   xm.h1("Header")              #     <h1>Header</h1>
   xm.p("paragraph")            #     <p>paragraph</p>
 }                              #   </body>
}                               # </html>

Pages: 1, 2, 3, 4, 5, 6, 7

Next Pagearrow





Sponsored by: