Fetches: Bringing Your ActionController its Slippers

There is a piece of code that shows up more than 80% of the controllers that I write, and it goes a little something like this:

class UsersController < ApplicationController
  def user
    @user ||= User.find(params[:id])
  end
  helper_method :user
end

A simple memoization method to allow me to easily grab the parameter-referred user in all of my actions. If I’m using nested routes, that means I can write two, maybe three of these methods into a controller. I’m basically using slight variations on the same code 20 different times in an application. Since we live in a world that loves to be DRY, I thought, “I can do better.”

Fetches: Memoizing Your Parameter Record Retrieval

Fetches is a simple extension to ActionController that lets you simply define those kinds of fetch methods on a one-line command. For the example above, I can rewrite it like so:

class UsersController < ApplicationController
  fetches :user
end

That’s pretty useful! Not only can I call the “user” method from the controller, but it’s automatically helperized so that I can use the same call in my views. Of course, there are times when more advanced fetching is called for, say using a method other than find or storing to a different variable name. Let’s take a look at a slightly more complex example:

# assuming a route like /users/:user_id/articles/:id
class ArticlesController < ApplicationController
  fetches :user, :as => :author, :from => :user_id, :using => :find_by_login
  fetches :article
end

Now if I were to call “author” in any of my controller actions, it would be equivalent to User.find_by_login(params[:user_id]). Similarly, calling “article” is equivalent to Article.find(params[:id]). The “from” option can also take a Proc in case your fetching is not simply a parameter key:

class UsersController < ApplicationController
  fetches :user, :from => Proc.new{ |c| c.params[:user_id] || c.params[:id] }
end

The main advantages to fetches are brevity, clarity and DRYness. I’ve found that this method covers every use case for parameter-based fetching that I’ve needed, and as such provides a much simpler, more readable, and shorter way to fetch models for use in your controller and views.

Installation

Fetches is available as a gem as well as in traditional plugin format. To install as a gem, add this to your environment.rb:

config.gem 'mbleigh-fetches', :source => 'http://gems.github.com', :lib => "fetches"

To install it as a traditional plugin:

script/plugin install git://github.com/mbleigh/fetches.git

Resources

The source is available on GitHub, the Acts As Community project is there for general discussion, and the Lighthouse is there for bugs and feature suggestions.

UPDATE: A commenter requested that the plugin be able to handle creation of new records in addition to fetching existing records. I have added in the :initialize option to do just this. Examples:

fetches :user, :initialize => true # initialize from params[:user]
fetches :user, :initialize => :author # initialize from params[:author]
fetches :user, :initialize => Proc.new{ |c| {:login => c.params[:login], :email => c.params[:email]} }
Share:

Comment on this post (5 comments)


Using HTTP Status Codes for Rails AJAX Error Handling

A problem that often arises in AJAX-based web applications is how to handle it when things go wrong. The user should be informed of the problem in a descriptive manner, but obviously the internal workings of the application should not be revealed. A generic and useful way to handle this problem is to use HTTP Status Codes to indicate the type of failure, and use the javascript to cope appropriately.

In this example I will be using jQuery, but the principles behind are just as applicable to Prototype or any other Javascript library.

Your Friends 403 and 500

Anyone who’s built a Rails site is familiar with the 500 error. That’s the generic exception code thrown whenever something goes wrong in your application. Users should, hopefully, never ever see this when they’re using the site. However, oftentimes there are exceptions or errors that users should experience just as result of improperly filling out fields, permissioning, etc. So how do we differentiate?

The Rails render method has the ability to render out an arbitrary HTTP Status Code (i.e. 500 for error, 404 for not found, and many more). The “403 Forbidden” code means that the server understood the request made of it, but is refusing to complete it. This sounds like an apt description for typically “caught” exceptions. So let’s use the 403 code to intelligently handle the exceptions that we want to be seen by the user.

In the controller

Let’s take the simplest example, an invalid record. If you are creating a record via AJAX, a flash[:error] with a render :action => "new" is not going to suffice. Let’s try something like this instead:

class ItemsController < ApplicationController
  def create
    Item.create!(params[:item])
    # continue on your merry way if it works
  rescue ActiveRecord::RecordInvalid => e
    respond_to do |format|
      format.html { 
        flash.now[:error] = "There was a problem creating the item." 
        render :action => "new" 
      }
      # Render out the validation failed message with a
      # 403 status code.
      format.js { render :text => e.message, :status => 403 }
    end
  end
end

All right, now that we’ve got it handled on the controller side, it’s time to work some Javascript magic on our AJAX call.


$('a#ajax_link').click(function() {
  $.ajax({
    url: '/items', 
    success:function(data, textStatus) {
      // do success things
    },
    error:function(request, textStatus, errorThrown) {
      // Use the specific message for a 403, but
      // a generic failure message for a 500
      var message = (request.status == 403) ? 
        request.responseText : "An unknown error occurred. Support has been contacted.";
      // Simple alert for example, but you can handle
      // however you want, such as populating an error message
      // div and making it appear.
      alert(message);
    }
    return false;
  });
});

Now when your AJAX request fails, it will render a user-friendly error message if it’s an ‘expected’ error or a generic message if the request fails with an unexpected exception.

This is a simple example, but by building a general framework for error expectations you can make it much easier to provide user-friendly error handling that gives them all of the information they need without revealing any of your internal processes.

Share:

Comment on this post (1 comment)


Mobilize Your Rails Application with Mobile Fu

Let's face it, iPhone interfaces are awesome, but they can only cater to a fraction of the mobile market. What are you to do if you want to satisfy the rest of the mobile world? Mobile Fu helps to make this job much easier by automatically detecting mobile devices that access your Rails application. People can access your site from a Palm, Blackberry, iPhone, Nokia, etc. and it will automatically adjust the format of the request from :html to :mobile.

Learn Mobile Fu

First off, just install the Mobile Fu plugin into your Rails application.

script/plugin install git://github.com/brendanlim/mobile-fu.git 

Start by adding this one line to your ApplicationController.

class ApplicationController < ActionController::Base
  has_mobile_fu
end

Once this is in place, any request that comes from a mobile device will be be set as :mobile format. It is up to you to determine how you want to handle these requests by creating the .mobile.erb versions of your views that are to be requested. Also, I recommend that you setup a before_filter that will redirect to a specific page depending on whether or not it is a mobile request. How can you check this?

is_mobile_device? # => Returns true or false depending on the device

You can also determine which format is currently set in by calling the method below.

is_mobile_view? # => Returns true or false depending on current req. format

If you want the ability to allow a user to switch between ‘mobile’ and ‘standard’ format (:html), you can just adjust the mobile_view session variable in a custom controller action.

session[:mobile_view] # => Set to true if request format is :mobile and false
                           if set to :html

What About Custom Mobile Styling?

Different devices need different styling. Don’t worry though, we’ve got this baked in to Mobile Fu (thanks to Intridea's own Michael Bleigh, who created Browserized Styles for letting me modify his code). If you are including a css or sass file via stylesheet_link_tag, all you have to do is add _device to the name of one of your files to override your styling for a certain device. The stylesheet that is loaded is dependant on which device is making the request.

Supported stylesheet override device extensions at the moment are: blackberry, iphone, mobileexplorer, nokia, palm

e.g., Accessing a page from a Blackberry.

<%= stylesheet_link_tag 'mobile.css' %>  

Ends up loading mobile.css, and mobile_blackberry.css if the file exists.

Feature Requests

You can check out Mobile Fu's very own project page at Acts As Community. If you have any problems or would like me to add a certain feature, please create a ticket at http://blim.lighthouseapp.com/projects/14490-mobile-fu/. Also, feel free to fork Mobile Fu and make any enhancements you please from its GitHub location at: http://github.com/brendanlim/mobile-fu/tree/master

Share:

Comment on this post (10 comments)


UberKit Update: UberForms To Ease Form Building

Last week the Uberkit kicked off with some helpers to make your menu-building much easier. This week we’re following it up with UberForms, a Form Builder that DRYs up your repetitive form stresses. Let’s see how it works!

Building an Uber-er Form

UberForms automatically generate all of the standard boilerplate HTML that goes around your forms. By wrapping everything up in an easily style-able package, it becomes a much easier business to make new forms as well as re-use form styling across projects. With the form markup taken care of, you can focus on the more important aspects of your UI building and keep your views deadly clean.

While UberForms are available as a standard form builder (Uberkit::Forms::Builder), you may find it more useful in its helper form (automatically available when the UberKit plugin is loaded:

<% uberform_for :user do |f| %>
  <%= f.text_field :login %>
  <%= f.password_field :password %>
  <%= f.submit "Submit"%>
<% end %>

This will automatically be translated into some nice, CSS-ready HTML:

<form method="post" class="uberform" action="/users">
  <div class="field_row">
    <label for="user_login">Login:</label>
    <input type="text" size="30" name="user[login]" id="user_login" class="text_field"/>
    <br/>
  </div>
  <div class="field_row">
    <label for="user_password">Password:</label>
    <input type="password" size="30" name="user[password]" id="user_password" class="password_field"/>
    <br/>
  </div>
  <button type="submit">Submit</button>
</form>

You can also change the label, add a description or help text to a field by adding the relevant options:

<%= f.text_field :login, :label => "Username", 
                         :help => "Only a-z and underscores.", 
                         :description => "The name you will use to log in." %>

Becomes…

<div class="field_row">
  <label for="user_login">Username:</label>
  <input type="text" size="30" name="user[login]" label="Username" id="user_login" help="Only a-z and underscores." description="The name you will use to log in." class="text_field"/>
  <span class="help">Only a-z and underscores.</span>
  <span class="description">The name you will use to log in.</span>
  <br/>
</div>

Finally, you can create custom HTML inside an UberForm field by passing a block:

<% f.custom :label => "State", :for => "user_state" do |f| %>
  <%= state_select :user, :state %>
<% end %>

Becomes…

<div class="field_row">
  <label for="user_state">State:</label>
  <div class="pseudo_field">
    <select id="user_state">...</select>
  </div> 
  <br/>
</div>

Easy, right? That’s all there is to it, now you can be UberForming to your heart’s content

Installation

To install the UberKit (which includes more than just forms) you can do so either as a gem or a traditional plugin. As a gem, just add this to your environment.rb:

config.gem 'mbleigh-uberkit', :lib => 'uberkit', :source => 'http://gems.github.com'

As a traditional Rails plugin:

script/plugin install git://github.com/mbleigh/uberkit.git

The Future of the UberKit

These two pieces are pretty helpful, but there’s more coming for the UberKit. Stay tuned for more updates, including more hooks and ways to customize the UberKit to fit your needs as a developer.

Share:

Comment on this post (0 comments)


iPhone 3G Released Today - iHysteria Ensues

Posted by on July 11th, 2008.

Ever since it's announcement at WWDC 2008, most of us have been waiting anxiously to get our hands on the new iPhone 3G. If you haven't been keeping up with the news or have just been in a coma for the past few weeks, you'd know that the second coming of the iPhone was to be released today at Apple and AT&T stores nationwide.



I arrived at the Apple Store at Lenox Mall in Atlanta, GA around five in the morning and ended up being the fifth person in line. Quite surprising, since the Apple Store in New York City had people lining up since last week. After purchasing and activating my new iPhone 3G, I had a chance to play with all of its great new features.

The first thing you'll notice is that the once silver backing has been replaced with a shiny, plastic back. The 8GB iPhone 3G ($199) only comes in black, whereas the 16GB iPhone 3G ($299) comes in either black or white. Surprisingly, the new plastic back, which has a nice curve to it, feels high quality and fits very nicely in your hand. My only gripe though, is that the black color is very prone to smudges and finger prints. Metal has replaced the old plastic volume, power, and silence switch, which also add to a sturdier feel. The recessed-headphone jack is also now no more, allowing you to ditch the clunky adapters that were needed for the first generation iPhone. Also, the chrome bezel around the edges has been pushed back, which gives off the impression that the face is larger, even though the front dimensions are exactly the same as the previous generation.

So, the iPhone 3G is named the way it is for a reason. Finally, you can get 3G speeds on AT&T's HSDPA network, which blows EDGE out of the water. I've gotten accustomed to EDGE speeds over the past year and having pages load up to 2.4x faster is a luxury I don't ever want to live without again. Now I can browse all of my favorite sites without spending so much time waiting for everything to load.



If you had a first generation iPhone, you probably didn't use the speakerphone that much because it was quite worthless. It's now quite loud. The much louder volume of the speakerphone is definitely something that I am very happy about. Now, I can hear my calls loud (very) and clear. Speaking of clarity, many have said that the incoming and outgoing voice quality has been vastly improved. I've noticed a much cleaner, crisper sound while on the phone, but nothing dramatic.


One of the coolest new features is the GPS capability. You now get 'real' GPS, unlike the cellphone tower triangulation that was used in the previous generation iPhone. You don't get voice guided, turn by turn directions out of the box, but it's really neat to see that blue, pulsating dot, smoothly move through the map, showing you exactly where you are. I had a fun time using it on the way back home from the Apple Store. It's also been confirmed that Navigon, will be producing a third-party app, available in the App Store sometime soon, that will provide real turn-by-turn navigation.



Speaking of third party applications, this is really where the new 2.0 firmware shines. The App Store allows you to purchase either paid-for or free applications, right from your new iPhone 3G. There are over 500 different applications already available during launch time. The majority of the applications now are not free, but the average price per application seems to fall between $5 and $10.

Also, anybody can develop these applications with the iPhone SDK. As the developer, you can take advantage of Multi-Touch interface, the accelerometer, GPS, real-time 3D graphics, and 3D positional audio to create some amazing applications. You can also choose to let your product be downloaded for free or you can charge a price. If you decide to charge a price, you agree to pay Apple 30% of the final purchase price. The App Store is proving itself to be a great place for developers to get their products directly to the consumer which an amazing amount of ease.



There are many other great features with the 2.0 firmware that I haven't mentioned, push integration with Exchange and MobileMe, bug fixes, and much more - to list them all, would take quite some time. The iPhone 3G is a nice upgrade from the original iPhone, and if you haven't gotten an iPhone yet, the lowered price and the great new features make it an amazing deal. Look out for some great iPhone applications from us in the future.

Share:

Comment on this post (0 comments)


UberKit: Building A Rails UI Swiss-Army Knife

So many of components we build into our web applications have a grain of an extractable element, a standardization waiting to happen. Starting today, I am putting together a “Standard UI Kit” for all of the tools that help me build interfaces faster. Together, they are called the UberKit. This week, the first segment is coming: UberMenus.

UberMenu: Abstract Menu Generation

Most people who build interfaces will build their menus with the same structure over and over. I finally took the time to abstract this out into a single helper that can pretty much serve all of my navigational needs. Here’s how you use it in a view:

<% ubermenu do |m| %>
  <% m.action 'Home', '/' %>
  <% m.action 'Users', users_path %>
  <% m.action 'Log Out', logout_path, :class => "special" %>
<% end %>

Becomes this HTML (assuming you’re at the document root):

<ul>
  <li class="first current first_current"><a href="/">Home</a></li>
  <li><a href="/users">Users</a></li>
  <li class="special last"><a href="/logout">Log Out</a></li>
</ul>

The current class will automatically be set on whichever page responds to the built-in Rails helper current_page? and the action syntax behaves just like a link_to. If a given action has multiple classes, they will also be joined with underscores as an additional class for browsers that do not support multiple class declarations. But in addition to easily creating simple menus, you can also easily generate multi-level navigation menus:

<% ubermenu 'nav' do |m| %>
  <% m.action 'Home', home_path %>
  <% m.submenu 'Services', services_path do |s| %>
    <% s.action 'Service A', service_path('a') %>
    <% s.action 'Service B', service_path('b') %>
  <% end %>
<% end %>

Which will become this HTML:

<ul id='nav'>
  <li class='first current first_current'><a href="/">Home</a></li>
  <li class='last'><a href="/services">Services</a>
    <ul>
      <li><a href="/services/a">Service A</a></li>
      <li><a href="/services/b">Service B</a></li>
    </ul>
  </li>
</ul>

Installation

UberKit is available both as a gem and a traditional plugin. For the gem version, add this to your environment.rb:

config.gem 'mbleigh-uberkit', :source => "http://gems.github.com/", :lib => "uberkit"

Or as a traditional plugin:

script/plugin install git://github.com/mbleigh/uberkit.git

Future of the UberKit

While UberMenu is a useful tool, the UberKit will continue to grow over time, so stay tuned for additions (next on the slate: UberForm). It may also grow to include some common styles and javascripts that can be used in conjunction with the helpers to provide an even easier track to a full-fledged UI.

Resources

As always, the source is on GitHub and there is an Acts As Community Profile available as well. If you have any problems with it or would like to request new features, enter them on the Lighthouse project.

Share:

Comment on this post (1 comment)


What the World Needs Now is CSS3

Posted by on July 2nd, 2008.

The discussion around HTML 5 has been heating up recently, with people advocating to get it finalized and implemented sooner rather than later (and lamenting the ulterior motives of major browser vendors in lobbying for specs). I simply can’t get passionate about this fight, much as I’ve tried. While some of the things that HTML 5 offers will certainly be a boon for web developers, by and large the issues that it addresses (in terms of interactivity) are surmountable simply by using the excellent Javascript libraries we’ve all become dependent upon. The next version of the CSS specification, however, is an entirely different story.

I recently started a new project and as an experiment decided to play with using the non-final border-radius implementations available in Firefox and Safari. After using it for about 15 minutes, I decided that I would simply forgo rounded corners in the interface for Internet Explorer. After using it for three days, I am wondering why every designer and developer on the internet isn’t simultaneously demanding immediate forced adoption of CSS3.

Styling is Fun Again

Our interfaces and style tastes have grown much more complex as the web has grown up, but the tools we use to implement those styles haven’t been keeping up. It shouldn’t feel like a trip to the dentist just to get a box to have some rounded edges. It shouldn’t be a nightmare to try to use translucent pngs for overlays (admittedly this has nothing to do with CSS3 and everything to do with IE6, the browser that won’t die no matter how much we pray).

I can tell you that styling on the edge doesn’t just feel good, it feels amazing. I’m able to implement in a few seconds what I might otherwise spend three hours styling while polluting my markup with hack tags.

Rounded Corners: Nemesis of Designers Everywhere

There is no good way to make rounded corners. The javascript libraries are buggy, images are limited in practicality, and getting it just right in all browsers is downright painful and usually ends up with markup something like this (and a whole mess of CSS to go with):

<div class='rounded'>
  <div class='tl'>
    <div class='tr'>
      <div class='bl'>
        <div class='br'>
          So much for semantics...
        </div>
      </div>
    </div>
  </div>
</div>

In the CSS3 specification, the same effect is achievable like so:

.rounded { border-radius: 10px; }

But it’s not just a convenient way to shortcut the hacks to which we’ve all grown accustomed, it opens up entirely new possibilities for design that would simply not be worth the effort to hack without it.

Lead By Example

Let me explain what I mean by example. Form design has always been one of the trickiest parts of web design, what can we do with a little CSS 3 magic? Let’s say we have a simple form that takes a person’s name:

<form id='sample_form'>
  <label for="name">First Name:</label>
  <input type='text' name="name" id="name"/><br/>

  <label for="name">Last Name:</label>
  <input type='text' name="name" id="name"/><br/>

  <button type="submit">Submit</button>
</form>

Simple enough, this turns out looking something like this:

Now we can add some standard CSS to make it look a little more acceptable:

label {
  display: block;
  float: left;
  width: 100px;
  font-weight: bold;
  padding: 4px 5px;
  font-family: Verdana, sans-serif;
  font-size: 12px;
  margin-bottom: 5px;
  clear: both;
  text-align: right;
}

input {
  font-size: 12px;
  margin-bottom: 5px;
}
button {
  margin-left: 115px;
  margin-top: 10px;
}

And our result is a perfectly usable form:

But what if we use just a taste of what CSS3 has to offer? We can make a form that looks completely unique without using a single image:

label {
  display: block;
  float: left;
  width: 100px;
  padding: 4px 5px;
  border: 2px solid #037;
  background: #06a;
  color: #fff;
  font-family: Verdana, sans-serif; 
  font-size: 12px;
  margin-bottom: 5px;
  font-weight: bold;
  clear: both;
  text-align: right;
  border-radius: 13px;
  border-top-right-radius: 0px;
  border-bottom-right-radius: 0px;
}

input {
  background: #fff;
  border: 2px solid #8ac;
  border-left: 0px;
  padding: 5px 5px;
  margin-top: 0;
  margin-bottom: 5px;
  margin-left: 0;
  border-radius: 5px;
  top-left-radius: 0px;
  border-bottom-left-radius: 0px;
}

button {
  background: #080;
  color: #fff;
  border: 2px solid #060;
  font-size: 12px;
  font-weight: bold;
  margin-left: 112px;
  padding: 5px 10px;
  border-radius: 13px;
}

It’s a hefty chunk of code, but anyone experienced in writing CSS can knock something like that out in about five minutes. The result is well worth it:

This kind of styling opens up with the application of just a single new attribute from the CSS3 draft specifications. Designers have had to hack, cheat, and wrangle every semi-complex interface that has been developed in the last 5 years thanks to the limitations of CSS (and more specifically the limitations of Internet Explorer), but it doesn’t have to stay that way forever.

State of the Browser

The complete CSS3 spec is not coming to a browser near you any time soon (more accurately not all browsers), and that’s a real shame. It brings to the table powerful new tools that can really enable the kind of semantic markup that we all wish was possible with today’s browsers. Rounded corners are just the “tip of the iceberg”; once CSS3 sees widespread adoption, interface design will take a leap forward unlike any it has seen before.

In the meantime, keep an eye out on the WebKit Nightlies for cutting edge CSS implementations (just added: CSS Variables). Five years from now we’ll look at the troubles we used to have and laugh. Until then, a person can dream…

Share:

Comment on this post (0 comments)