• Shortcuts : 'n' next unread feed - 'p' previous unread feed • Styles : 1 2

» Publishers, Monetize your RSS feeds with FeedShow:  More infos  (Show/Hide Ads)


Date: Sunday, 01 May 2011 23:37

Most Rails developers are familiar with generating RESTful URLs polymorphically by simply passing an object to one of many helper methods that expects a URL, such as link_to and form_for:

# In Routes
resources :articles

# In View:
form_for @article do |f|

This capability extends beyond just single objects, supporting nested routes and specific action targeting; for example:

# In Routes:
namespace :admin do
  resources :categories do
    resources :articles
  end
end

# In View
form_for [:admin, @category, @article] do |f|

Problem

One problem I’ve run into with some frequency, however, is using this polymorphic path approach when the class name of the ActiveRecord model does not quite correspond directly with the resource name. This occurs most frequently when you want a little more context in your model naming which may not be necessary in routes. For example, lets look a domain model with customers having many customer locations:

# Models:
class Customer < ActiveRecord::Base
  has_many :locations, :class_name => "CustomerLocation"
end

class CustomerLocation < ActiveRecord::Base
  belongs_to :customer
end

# Routes:
resources :customers do
  resources :locations
end

In the above example, the model name is "CustomerLocation", but the resource name as specified in the routes is just "locations", since the context of customers is already well-established from the nesting. The problem with this is when we try to use our regular polymorphic path solution:

form_for [@customer, @location]
# Tries to generate: customer_customer_location_path(@customer, @location)

Many people when running into this will just do away with using the clean polymorphic path solution entirely and instead provide the URL explicitly:

form_for @location, :url => customer_location_path(@customer, @location)

This of course works but isn't exactly ideal.

Solution

While it might look like it's using the class name to construct the url helper method name, it's in fact using "model_name" instead (which defaults to the class name). But, this can be overridden!

class CustomerLocation < ActiveRecord::Base
  def self.model_name
    ActiveModel::Name.new("Location")
  end
end

After this, the polymorphic path [@customer, @location] works as we would expect.

Another common situation where this technique becomes useful is if you are working extensively with namespaced models. This is tricky because the namespace ends up becoming part of the model name, which almost surely does not map to your resource hierarchy:

# Model:
class Core::Customer < Core::Base
end

# View:
form_for @customer
# Tries to generate: core_customer_path(@customer)

Overriding model_name will allow you to explicitly define "Customer" as the model name, despite it being namespaced within "Core". But we can do better than that - if you have a base model for your namespace (as I believe is always a good practice), just put this in the base model:

class Core::Base < ActiveRecord::Base
  def self.model_name
    ActiveModel::Name.new(name.split("::").last)
  end
end

Although this technique has served me well in many apps, do be aware that the model name is used in some other instances throughout Rails such as error_messages_for, so do use this with care.

Though all of the above examples are for ActiveModel/ActiveRecord 3.0 or higher, the same technique will work in Rails 2.3 by simply using "ActiveSupport::ModelName" in place of "ActiveModel::Name".

Author: "benhughes" Tags: "Rails Techniques"
Comments Send by mail Print  Save  Delicious 
Date: Saturday, 01 Jan 2011 07:47

Developers seem to rarely use validates_lengths_of with their models, despite there being an inherent maximum length on every string and text field – the one enforced by the database. Since table migrations in Rails set a fairly high maximum length for string attributes, most people don’t think twice about the possibly of that limit being exhausted. Even beyond this, there may be other reasons why the field limit is set fairly low, or perhaps you’re working with a legacy database.

Without validating maximum field lengths at the model level, ActiveRecord will still ship off the full field value as entered in an INSERT query. From there two things might happen, and this depends on the database itself.
1. It might fail the query with an ActiveRecord::StatementInvalid exception. Since this is an exception most developers don’t routinely handle, this could cause the entire request to fail. This occurs with SQL Server for sure, and possibly other databases.
2. It might accept the query and simply truncate the result to the field limit. This might sound better than #1, but IMO it’s actually worse: now you have an instance where the everything appeared to go along fine, but you might end up with missing data. This is the default behavior with MySQL.

There’s another reason why you should always validate field lengths, and that’s to limit the possibilities for a Denial of Service attack. If an attacker knows you aren’t validating field length and that whatever they’re providing is going straight into an SQL query and being sent to the database, they can craft extremely large requests that might fill up the pipe to the database. Even if the data doesn’t actually end up being inserted in full, they’ve tied up a database connection and – since the regular old “mysql” gem will block for the query result – a Rails process.

Unfortunately in order to do this properly you essentially have to write validates_length_of lines (or the equivalent ActiveRecord 3 form) for each attribute, with it’s maximum database length. To make this easy, I wrote a gem called validates_lengths_from_database that will introspect your database string field maximum lengths and automatically defines length validations for you.

To install, just include the gem in your Gemfile (works with Rails 2.3 and Rails 3.0):

gem "validates_lengths_from_database"

Then in your model you can activate validations:

  class Post < ActiveRecord::Base
    validates_lengths_from_database
  end

It also supports filter-style :only and :except options:

  class Post < ActiveRecord::Base
    validates_lengths_from_database :only => [:title, :contents]
  end

  class Post < ActiveRecord::Base
    validates_lengths_from_database :except => [:other_field]
  end

Note that this cannot be done at a global level directly against ActiveRecord::Base, since the validates_length_from_database method requires the class to have a table name (with the ability to load the schema).

For more information or to view the source, check out the project on GitHub: validates_lengths_from_database

Author: "benhughes" Tags: "Rails Plugins, Rails Techniques"
Comments Send by mail Print  Save  Delicious 
Date: Thursday, 02 Sep 2010 03:48
Six years ago I moved to Rochester, a city that at the time I had only vague recognition of, to start my life as a college student at RIT.  In those past six years I’ve gotten to know and grown to like the city I began my “adult life” in, despite the horrid winters.  Having grown personally a great deal in Rochester over the past six years, I’ve come to consider Rochester my “home” (over my parents’ home in Williamsport, PA).  After college, I decided to continue working independently based out of Rochester to do freelancing full-time.  Since then I’ve had the opportunity to meet and work with many great people, especially at Coworking Rochester, who have greatly enriched my daily life.
But, the past nine months have had me itching for a change.  Many of my college friends have moved on, and somehow there seems like there’s less for me in Rochester than there was when I was a college student.  The winters are also a depressing time of year when I feel like I’m only able to live half of my life.  I have visited many cities in the US and gotten to experience what life in another city might be like.  Most of all, I really just feel like taking a chance on something new – a new adventure.
So, after several trips there and much deliberation, I have decided to move to San Diego in November.  There are several reasons why I chose San Diego:
  • San Diego is a “big city”.  I’ve always longed to live in a larger city where more opportunities of all kinds await.
  • San Diego weather is outstanding.  Being able to play tennis every single day is a major plus.
  • San Diego has a lot of charm, particularly in the many communities outside of downtown such as North Park and Hillcrest.
  • My parents are moving (for half of the year) to Palm Springs, a city only a couple hours away.
  • Although paling in size to San Francisco, San Diego seems to have a decent tech community (and Ruby community).
  • The entire area seems far more laid back, and people are friendlier.
  • I do actually know a few people out there, which is more than I can see for most west coast cities.
I am in the process of shedding almost all of my personal belongings.  Before I leave, my property will consist of my keyboard (piano), some clothes, and my laptop.  On November 5th I will begin the drive out to San Diego, stopping in RubyConf in New Orleans along the way.
In conjunction with this move I’ll also be doing quite a bit of traveling between now and November 5th when I begin the drive out.  For part of September I’ll be taking advantage of the JetBlue All You Can Jet pass to visit Chicago, Boston, Washington DC, Seattle, Portland, San Francisco, Los Angeles, San Diego, and Phoenix, not mainly to tour but to just be in a different city each day and take in the vibe.  During this trip I’ll be working more or less like normal.  After that, and since my apartment lease ends September 30th, I’ll be spending the month of October “homeless” on an around-the-world trip patched together with cheap flights and hostel stays.  On this trip I’ll be starting in San Diego to look for apartments, then flying around the world westward to Vancouver, Hong Kong, Singapore, Bangkok, Dubai, Abu Dhabi, Istanbul, Athens, Barcelona, and finally New York.  I’ve scheduled a few days in each city and will be trying to see as much as possible.  I’m absolutely stoked about these two trips since I have such a huge passion for travel.  I doubt the low-cost opportunities that have made these trips so extremely cheap and affordable by me will ever come about again.
During these two trips I’ll be blogging along the way and maintaining a travel journal at Everlater:
During the next 2 months I will be flying 54,000 miles – over twice the circumference of Earth – and driving over 3,000 miles on what is by far the biggest adventure I’ve ever been on.  This exciting trip will be a great “reset” before I start to rebuild my life in a new city.  Despite this, the move will also be stressful and challenging for many weeks as I get settled into San Diego and start to meet new people, something I don’t always have an easy time doing.  Though challenging, I think it will be worth it in the long run.
To all of my friends in Rochester: you will be missed.  Thank you for the great past several years.  I’ll be back from time to time, and if you’re ever out in the San Diego area – do let me know!
Author: "benhughes" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Wednesday, 07 Jan 2009 20:10

If in your data schema most or all of your fields are NULLable (the Rails default in migrations), you may have run into the issue whereby sometimes your fields are blank and sometimes they are NULL, two distinct representations of a “no data” state.  This arises in Rails often because when you submit a form and the user doesn’t fill in a value, the value sent to the database is an empty string, even if you may prefer the field to just remain NULL.

Enter nilify_blanks, my solution to handling this problem generically in your models.  With nilify_blanks you can specify the fields you want “nilified” (or default to all content fields) upon save if the field is blank.  This allows you to regain some consistency in how you represent data in the database.   Use of the plugin is best-explained with some examples:

Basic Examples

  # Checks and converts all fields in the model
  class Post < ActiveRecord::Base
    nilify_blanks
  end

  # Checks and converts only the title and author fields
  class Post < ActiveRecord::Base
    nilify_blanks :only => [:author, :title]
  end

  # Checks and converts all fields except for title and author
  class Post < ActiveRecord::Base
    nilify_blanks :except => [:author, :title]
  end

Specifying a Callback
Checking uses an ActiveRecord before_save filter by default, but you can specify a different filter with the :before option. Any filter will work – just first remove the “before_” prefix from the name.

  class Post < ActiveRecord::Base
    nilify_blanks :before => :create
  end

  class Post < ActiveRecord::Before
    nilify_blanks :before => :validation_on_update
  end
Author: "benhughes" Tags: "Rails General, Rails Techniques, Uncateg..."
Comments Send by mail Print  Save  Delicious 
Date: Saturday, 03 Jan 2009 21:05

I recently had a frustrating discussion with a developer friend of mine concerning building web applications to support Internet Explorer 6 that highlighted a recurring theme of technology people misunderstanding business and economic decision-making.  In it I found myself trying to defend a deliberate decision in an application I develop not to support IE6.  His take was that because so many internet users still use IE6, there’s just no reason why we should not build our applications to support the browser.

Now there’s no doubt that Internet Explorer 6 continues to have large penetration in the browser market.  But this fact alone resulting in a categorical dismissal of the deliberately not supporting IE6 misses some key pieces of economic reasoning that must be considered.

Before outlining the reasoning, let’s just accept the false assumption that browser usage numbers alone should dictate your decision regarding browser support.  If this is the case, what’s the breaking point?  At what percentage use do you decide not to support – what’s the magic number?  Making decisions this way is rather naive – any choice here is mostly arbitrary and bears to relevance to the trade-off of costs and benefits or the other considerations I outline in the rest of this post.  The core objective here is to balance the benefit of having more users access to your applications (or more correctly, the marginal revenue derived from the additional customers using only IE6, since it isn’t safe to assume that browser and revenue-per-customer are uncorrelated) against the anticipated cost of making your application IE6-compatible. As such, the relevant decision should carefully consider this trade off.  To help make this decision, there are considerations on both the cost and the benefit side:

Considerations on the Benefit Side

One thing that’s commonly done is to cite browser numbers as of today as if that’s the complete picture.  As a case in point look at Google Chrome: numbers for this browser are quite low but many developers are rushing to provide support for it because of the future expectation of higher numbers.   Basing your decision on current penetration numbers at a particular point in time would be like performing stock valuation with last fiscal years profit only.  Many companies that aren’t even profitable are worth magnitudes larger than established revenue-sustaining firms.  Therefore, when considering browser penetration, we really should be thinking not only about today’s numbers but also about anticipated numbers in the future, since presumably the application in development will last at least a year or two.  Put simply, trends matter.Another important point to consider is your target audience.

It doesn’t come as a surprise that browser choice does has some correlation with technical ability, so if your application targets hip, young internet users well-versed in other web 2.0 applications, you can bet that the percentage of that group using IE6 is significantly less than the percentage of older folks who barely check their e-mail and use an older machine.

Yet another important consideration, particularly if you are working on an internal project, is what degree of control you have over your users’ web browser.  For example, if you are working on an internal application used within your company, and the corporate standard is to use Firefox, then you aren’t going ot have much of a problem with IE6.   Even some applications, especially at first, are introduced to a smaller set of users with whom you may actually speak to in person and be able to influence the browser used with the application.  This is the case in one of the applications I work on and hence we haven’t found it worth it to support IE6 yet.

Considerations on the Cost Side

Implementing support for IE6 is not free.  Every web developer on Earth has a profound hate for Internet Explorer 6 with all it’s quirks, bugs, and non-compliance with established standards.  Creating semantic HTML/CSS markup that works well in IE6 is hard enough, but writing working JavaScript is five times more difficult to create and twenty times more difficult to debug.  Even when it’s working, often times you’ll have implemented hacks and other code smell that detracts from quality of the codebase.  Doing all this of course costs money since ultimately you are paying developers to produce the code and debug it for IE6.  In many cases this can be a significant additional expense.

Most importantly, the magnitude of this additional expense is extremely dependent on the specifics of the application.  A basic brochure ware website with no JavaScript would cost significantly less to support than a rich, web 2.0 application with significant interactivity.

Although it’s very difficult to quantify this cost (at least, more difficult than quantifying labor cost), there’s also something to be said for reducing code quality and structure for the sake of supporting IE6.  Extra DIVs, CSS hacks, less straightforward CSS due to lack of newer CSS selectors, and conditional statements in JavaScript all have a “cost” in a most abstract sense to the elegance of your codebase and may have additional maintenance costs in the future as you try to maintain a less clean codebase.

Another misunderstanding in general when thinking about costs and decision-making at the margin is that saving $1,000 in developer pay may not be the “real” economic cost here since keeping $1,000 cash may not be (and most certainly is not) your next best alternative, a concent economists call “opportunity cost”, which is the real cost that you should consider when making decisions.   Now in a more traditional setting your opportunity cost isn’t much higher than your cash expenditure so substituting cash isn’t a bad approach, but in a face-paced startup that’s growing very quickly, often times your opportunity cost can be enormous as new features and development have tremendous value.  Saving $1,000 in labor can be substantial if that $1,000 in capital could otherwise be used towards implementing new features that you  value at much, much more than $1,000.

The point here is not whether or not it makes sense for my particular application to support IE6.  Certainly it makes sense for many sites, usually content sites and those sites not targetted to a younger crowd, to support IE6 in full.  My point here is that decisions like these should not be shallowly-reasoned or be subject to categorical dismissals.  In decisions like this, it pays to approach a decision analytically like an economist would – think carefully about the costs and benefits.  And choosing which browsers your application supports is pretty trivial compared to all the other kinds of decisions in developing software that would benefit greatly from an application of economic reasoning.

Author: "benhughes" Tags: "Economics, Rails General"
Comments Send by mail Print  Save  Delicious 
Date: Tuesday, 30 Dec 2008 22:28

I ran into a problem a while back of creating draft copies of ActiveRecord models for the purpose of establishing a draft/live system. I’ve since found a reason to resurrect this and publish it to GitHub and clean some things up. Check out has_draft on GitHub.

has_draft allows for multiple “drafts” of a model which can be useful when developing:

  • Draft/Live Version of Pages, for examples
  • A workflow system whereby a live copy may need to be active while a draft copy is awaiting approval.

The semantics of this as well as most of the inspiration comes from version_fu, an excellent plugin for a similar purpose of maintaining several “versions” of a model.

This was built to be able to be tacked on to existing models, so the data schema doesn’t need to change at all for the model this is applied to. As such, drafts are actually stored in a nearly-identical table and there is a has_one relationship to this. This separation allows the base model to really be treated just as before without having to apply conditions in queries to make sure you are really getting the “live” (non-draft) copy: Page.all will still only return the non-draft pages. This separate table is backed by a model created on the fly as a constant on the original model class. For example if a Page has_draft, a Page::Draft class will exist as the model for the page_drafts table.

Basic Example::

## First Migration (If Creating base model and drafts at the same time):
class InitialSchema < ActiveRecord::Migration

  [:articles, :article_drafts].each do |table_name|
    create_table table_name, :force => true do |t|
      t.references :article if table_name == :article_drafts

      t.string :title
      t.text :summary
      t.text :body
      t.date :post_date
    end
  end
end

## Model Class
class Article < ActiveRecord::Base
  has_draft
end

## Exposed Class Methods & Scopes:
Article.draft_class
=> Article::Draft
Article.with_draft.all
=> (Articles that have an associated draft)
Article.without_draft.all
=> (Articles with no associated draft)

## Usage Examples:
article = Article.create(
  :title => "My Title",
  :summary => "Information here.",
  :body => "Full body",
  :post_date => Date.today
)

article.has_draft?
=> false

article.instantiate_draft!

article.has_draft?
=> true

article.draft
=> Article::Draft Instance

article.draft.update_attributes(
  :title => "New Title"
)

article.replace_with_draft!

article.title
=> "New Title"

article.destroy_draft!

article.has_draft?
=> false

Custom Options::

## First Migration (If Creating base model and drafts at the same time):
class InitialSchema < ActiveRecord::Migration

  [:articles, :article_copies].each do |table_name|
    create_table table_name, :force => true do |t|
      t.integer :news_article_id if table_name == :article_copies

      t.string :title
      t.text :summary
      t.text :body
      t.date :post_date
    end
  end

end

## Model Class
class Article < ActiveRecord::Base
  has_draft :class_name => 'Copy', :foreign_key => :news_article_id, :table_name => 'article_copies'
end

Method Callbacks:
There are three callbacks you can specify directly as methods.

class Article < ActiveRecord::Base
  has_draft

  def before_instantiate_draft
    # Do Something
  end

  def before_replace_with_draft
    # Do Something
  end

  def before_destroy_draft
    # Do Something
  end
end

Block of Code Run for Draft Class:
Because you don’t directly define the draft class, you can specify a block of code to be run in its
context by passing a block to has_draft.

class Article < ActiveRecord::Base
  belongs_to :user

  has_draft do
    belongs_to :last_updated_user

    def approve!
      self.approved_at = Time.now
      self.save
    end
  end

end
Author: "benhughes" Tags: "Rails General, Rails Plugins, Rails Tool..."
Comments Send by mail Print  Save  Delicious 
Date: Wednesday, 26 Nov 2008 22:54

Message Block Example

One of the most common needs in any application I build is to have some abstract way of handling messages to end users.  Sometimes I’ll want to show a confirmation message or a warning.  Other times I’ll want to show a confirmation message but also show ActiveRecord validations.  While the error_messages_for helper in Rails works fairly well for showing ActiveRecord validation issues, I wanted a unified approach to handling this and flash messaging with multiple flash types in one package.

I blogged before about an approach I developed to solve this problem, I rolled my own message_block plugin.  The README file explains things pretty so be sure to check it out for more details, but here is the intro:

Introduction:

Implements the common view pattern by which a list of messages are shown at the top, often a combination of flash messages and ActiveRecord validation issues on one or more models. This allows for a nice, stylized block of messages at the top of the page with icons indicating what type of message it is (error, confirmation, warning, etc.)

This view helper acts as a replacement for error_messages_for by taking error messages from your models and combing them with flash messages (multiple types such as error, confirm, etc.) and outputting them to your view. This plugin comes with an example stylesheet and images.

Usage:

Once you install this, you should now have a set of images at public/images/message_block and a basic stylesheet installed at public/stylesheets/message_block.css. First you’ll want to either reference this in your layout or copy the declarations to your main layout. Then you can use the helper <%= message_block %> as described below:

The first argument specifies a hash options:

  • :on – specifies one or many model names for which to check error messages.
  • :model_error_type – specifies the message type to use for validation errors; defaults to ‘error’
  • :flash_types – specifies the keys to check in the flash hash. Messages will be grouped in ul lists according to this type. Defaults to: %w(back confirm error info warn)
  • :html – Specifies HTML options for the containing div
  • :id – Specifies ID of the containing div; defaults to ‘message_block’
  • :class – Specifies class name of the containing div; defaults to nothing.

Imagine you have a form for entering a user and a comment:

<%= message_block :on => [:user, :comment] %>

Imagine also you set these flash variables in the controller:

  class CommentsController
    def create
      flash.now[:error] = "Error A"
      flash.now[:confirm] = "Confirmation A"  # Note you can use different types
      flash.now[:warn] = ["Warn A", "Warn B"]  # Can set to an array for multiple messages
    end
  end

And let’s say that you want to show these messages but also show the validation issues given that both user and comment fail ActiveRecord validation:

  <div id="message_block">
    <ul class="error">
      <li>Error A</li>
      <li>User first name is required.</li>
      <li>Comment contents is required.</li>
    </ul>
    <ul class="confirm">
      <li>Confirmation A</li>
    </ul>
    <ul class="warn">
      <li>Warn A</li>
      <li>Warn B</li>
    </ul>
  </div>

Which will by default leave you with this look:

Message Block Example

message_block on GitHub

Author: "benhughes" Tags: "Rails Plugins, Rails Techniques"
Comments Send by mail Print  Save  Delicious 
Date: Saturday, 05 Jul 2008 14:22

The addition of named_scope in Rails 2.1 has revealed several elegant approaches for modeling complex problem domains in ActiveRecord.  One I came across recently while working on an app with a somewhat complex permissions system was a permission-based filtering mechanism.  In this case I was dealing with permission for a given user to manage an “office”, while a user could be at one of three permission “levels”, one of which has specific office assignments (or it’s assumed all are manageable if user.can_manage_all_offices is true). Lot’s of necessary conditional logic there.

Now a normal approach to such a task to “show a list of offices that the user can manage” (for a drop-down for an interface perhaps) might be something like this:

# In controller:
if current_user.can_manage_company?
  @offices = Office.find(:all)
elsif current_user.office_access_level? && current_user.can_manage_all_offices?
  @offices.find(:all)
elsif current_user.office_access_level?
  @offices.find(:all, :conditions => {:id => current_user.manageable_offices.map(&:id) })
else
  @offices = []
end

But this approach starts at the user level and, using a lot of conditional logic baked right into places we don’t want, makes different calls to Office, which isn’t very DRY, and certainly not consistent with fat models skinny controllers.  So I considered inverting this approach and instead starting with an office, and asking it what “is manageable by” a given user.  Consider this alternative:

# In office.rb
named_scope :manageable_by, lambda {|user|
  case
  when user.can_manage_company? then {}
  when user.office_access_level? && user.can_manage_all_offices? then {}
  when user.office_access_level? then {:conditions => {:id => user.manageable_offices.map(&:id)}}
  else {:conditions => "1 = 0"}
  end
}

# Then in controller:
@offices = Office.manageable_by(current_user)

This seems much more elegant to me.  I’m in general finding a lot of opportunities for inverting the way I designed something without named_scope to be more model-centric, so this approach helps further the design principle of “fat models, skinny controllers”. Sure you could do this before by defining your own methods and using with_scope, but named_scope just makes it all the more elegant.

Another advantage with using the named scope stuff is that you can chain scopes together. Let’s say that in another controller I want to do the same thing but instead restrict results to active offices only. I can create an “active” named scope that scopes :conditions => {:active => true}, then in the controller simply do this instead:

@offices = Office.manageable_by(current_user).active
Author: "benhughes" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Saturday, 28 Jun 2008 18:10

To me, the benefit of using JavaScript frameworks in an application cannot be overstated.  Though I’m also a fan of server-side frameworks, there is scarcely a reason not to use a client-side framework these days.  Of course the most common complaint against JavaScript frameworks is “bloat” and the long download time.  Funny that the most vocal of those complaining about the frameworks’ download time are those who haven’t even ever used a framework to experience it’s benefits.  The tradeoff of course is a noticeable load hit for some users on slower connections vs. architectural elegance, much higher productivity, more maintainability, and less code in general.  To me in most cases the trade-off is a no-brainer in any sufficiently modern web application, but not to all.

Released recently is the Google Ajax Libraries API which is basically a way of allowing browsers do download only one version of a given framework for all applications using that framework.  Currently most web applications host their own version of a given JavaScript library, which is inefficient across the spectrum of the internet since many sites are using the exact same library.  With Google Ajax Libraries you essentially reference Google’s hosted version of the library and the download hit is only incurred the first time a user visits any site using that framework.  So it’s quite likely that a user going to your site won’t have to download a thing – it’s as if the framework is at that point simply part of the user’s browser.

Of course this only works if it becomes widely used and I sure hope it will.  I’d encourange all developers to start using this in their production environments (development environments should still use local copies for local development:

Google AJAX Libraries API
Rails Plugin for Google AJAX Libraries API

Author: "benhughes" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Wednesday, 25 Jun 2008 16:40

I fairly often use the acts_as_tree plugin in my applications.  While acts_as_nested_set (and superior variants..) is more powerful, often times a simple two-level deep hierarchy is all I need and acts_as_tree is simple.  I’ve found the new named_scope functionality in Rails 2.1 to be very helpful when dealing with tree data structures.

Firstly, it’s somewhat rare that I have one single root node in the tree structure (which is apparently how it’s meant to be used).  Instead I’ll have multiple “parent” nodes designated with a NULL parent_id and children beneath.  In the past I’ve always done something like: find(:all, :conditions => {:parent_id => nil}) to grab the top entries.  Instead with nested set you can do this:

named_scope :top, :conditions => {:parent_id => nil}

#Then:
Category.top

Another common task when dealing with hierarchical categories is to query on the base object (products for example) for members that are “part of” that category. Specifically, part of in a 2-level heirarchy simply means “where id = ? or parent_id = ?” on the joined categories table. Because this involves a join it was somewhat clunky to do before. Now with nested set, on the product model I can declare this:

named_scope :in_category, lambda {|c| {:include => [:category], :conditions => ["categories.id = ? OR categories.parent_id = ?", c, c]} }

# Then:
Product.in_category(3)

I would also highly encourage you all to check out RailsCasts Episode 112 “Anonymous Scopes” by Ryan Bates where he outlines a pattern for handling conditions elegantly with searches using named_scopes in Rails 2.1, something I’ve always found to be lacking from Rails core and always resorted to using plugins like criteria_query.

Author: "benhughes" Tags: "Rails General, Rails Techniques, Rails T..."
Comments Send by mail Print  Save  Delicious 
Date: Wednesday, 04 Jun 2008 19:25

Though I’ve been extremely happy with leopard (in fact, why I finally bought a Mac), little quirks with spaces were frustrating.  Specifically, spaces seems to have been designed for users who want to place a separate application in each space.  I use spaces in a task-oriented manner where each space typically has a Firefox window, tabbed terminal, and TextMate.  Command-Tabbing and others workflow situations were just quirky.  Also, a huge annoyance was going into the terminal, typing “mate .” and having it open up a new TextMate window in whatever space already had a TextMate window.

I’m very pleased to report that 10.5.3 solves all of these problems, with one new option in the spaces dialog called “When switching to an application, switch to a space with open windows for the application.”  In fact, you want to uncheck this option if you are working in a task-oriented manner like me.  There were also some bug fixes in 10.5.3 which transcend this new option.

With these frustrations gone I feel very solid working with 3-5 project workspaces at once and can move efficiently within and among them.

Upgrade to 10.5.3 now if you haven’t already done so!

Author: "benhughes" Tags: "Personal"
Comments Send by mail Print  Save  Delicious 
Date: Saturday, 12 Apr 2008 19:30

I had an opportunity to play around with Phusion Passenger (mod_rails) which was just released yesterday. Before yesterday all that was available was an introductory video showing Passenger being configured, and I was quite impressed by it’s ease. Clearly one of the problems with Rails as a major platform right now is it’s hosting situation. Currently the best solution is to proxy HTTP requests from Apache or Nginx to a cluster of mongrels, which is tricky to set up and somewhat tedious – certainly not as as easy as a mod_php in Apache where things “just work”. Phusion set out to overcome this problem and release a module for Apache that hosts Rails applications easily. Here is what took me from a clean Ubuntu 7.10 slice from SliceHost to a working server with Passenger:Starting OutTo start out, I used the following *excellent* SliceHost articles to get some of the basic packages installed such as Ruby and MySQL:Ubuntu Setup – Part 1Ubuntu Setup – Part 2MySQL and RailsApache and PHPApache Virtual HostsVirtual Hosts & PermissionsNote my permissions gotcha below – you may not want to strictly follow their permissions advice (where the global does not have read permission).I also installed sqlite3 as this is now the default database package used in Rails 2.0:

$ sudo aptitude install sqlite3$ sudo gem install sqlite3-ruby

Installing the Passenger Apache ModuleUsing the simple instructions on the Passenger website, I ran:

$ sudo gem install passenger$ passenger-install-apache2-module

The passenger-install-apache2-module binary walks you through the installation of the Passenger. On the first run, it told me I didn’t have some software that was required:

* GNU C++ compiler... found* Ruby development headers... found* OpenSSL support for Ruby... found* RubyGems... found* Rake... found at /usr/bin/rake* Apache 2... found at /usr/sbin/apache2* Apache 2 development headers... not found* Apache Portable Runtime (APR) development headers... not found* fastthread... foundSome required software is not installed.But don't worry, this installer will tell you how to install them....* To install Apache 2 development headers:Please run apt-get install apache2-prefork-dev as root.* To install Apache Portable Runtime (APR) development headers:Please run apt-get install libapr1-dev as root.

Clearly the installer detected I was running Debian-based Linux and told me exactly what to do. No compile errors or nasty dependency issues, just simple and clear instructions. After installing the requisite software the installer compiled the Apache module and spit out this:

The Apache 2 module was successfully installed.Please edit your Apache configuration file, and add these lines:LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-1.0.1/ext/apache2/mod_passenger.soRailsSpawnServer /usr/lib/ruby/gems/1.8/gems/passenger-1.0.1/bin/passenger-spawn-serverRailsRuby /usr/bin/ruby1.8After you restart Apache, you are ready to deploy any numberof Ruby on Rails applications on Apache, without any furtherRuby on Rails-specific configuration!

Note that it didn’t find or attempt to find where apache modules are installed as the actual compiled modules is kept within the Ruby gems directory, it just told me what lines to include in my Apache configuration file. The last part of the installation says:

Deploying a Ruby on Rails application: an example.Suppose you have a Ruby on Rails application in /somewhere.Add a virtual host to your Apache configuration file,and set its DocumentRoot to /somewhere/public, like this:<VirtualHost>      ServerName www.yourhost.com      DocumentRoot /somewhere/public</VirtualHost>And that's it!

Now this is pretty cool… Passenger doesn’t even require virtual hosts to configure themselves as Rails applications. It will automatically detect a Rails application (I’m unsure of the actual criteria here) based on the DocumentRoot that you provide.So I added the necessary lines specified above to /etc/apache2/apache2.conf to load the module. Note that some deployments of Apache have their own way of managing modules; in Ubuntu there is a mods-available directory with individual configuration files for each module. You could split up the above commands to follow the convention for your system of choice, but for my purposes I just dumped the three lines into apache2.conf.Then I created a new Rails application and pointed DocumentRoot to the Rails public directory. Restart apache, and the site should then immediately work with no further configuration.Permissions Gotcha – Important!If you get:

RAILS_ROOT is not a directory.

The first time I got to this point I was running into an extremely obscure problem – Rails was reporting that RAILS_ROOT wasn’t a directory. After some debugging which involved hacking up the gem source code of both Rails and Passenger, I realized it was a permissions issue (what do you know). Passenger reports that it will run your Rails application as whatever user owns environment.rb. However, it will set the effective group to that user’s primary UNIX group, NOT the group that environment.rb is owned by. In my case, I set the group of all of the web files to www-data and no read or execute permissions whatsoever for other. I figured this would be sufficient since Apache runs as www-data. But in my case when Passenger got spawned, it got spawned running as bhughes:bhughes NOT bhughes:www-data, so it effectively couldn’t find the RAILS_ROOT directory and didn’t think it existed. You can design your permissions scheme however you want, but make sure you keep this in mind. I have an enhancement in Passenger’s ticketing system for fixing this and allowing you to manually set the effective group (you already can explicitly set the effective user through the RailsUser option).More Passenger ConfigurationThe Passenger User’s Guide is pretty good and includes some more specific configuration options you can choose, but the default appears to work fine. The Rails environment is by default set to “production” though this can be changed (sadly, only server-wide, not on a virtual-host basis – but there is an enhancement in the issue tracker for this feature).Restarting Your AppRestarting a Rails app hosted by Passenger is easy – simply touch a file called tmp/restart.txt within the Rails application root:

$ touch tmp/restart.txt

CapistranoBrian Ketelsen pointed out this Capistrano configuration which uses the touch tmp/restart.txt approach to restart and removes the .htaccess file which can cause issues:

namespace :deploy do  task :start, :roles => :app do  end  task :stop, :roles => :app do  end  task :restart, :roles => :app do    run "touch #{release_path}/tmp/restart.txt"  end  task :after_update_code, :roles => :app do    run "rm -rf #{release_path}/public/.htaccess"  endend

Diagnosing ProblemsOne of the absolutely wonderful things about Passenger is that problem diagnostics (regarding starting your Rails app) is fairly easy because Passenger includes its own nice error pages:Database Error ExampleFramework Initialization ExampleMemory ManagementOne of the issues with mongrel or thin is that they are constantly running and sucking up memory, even for sites that get very little traffic. This leads to a situation where hosting very low-traffic sites is very inefficient from a system resources perspective. This isn’t the case with PHP where memory usage spikes during traffic but is otherwise unused, allowing multiple sites to leverage the on and offs and maintain a pretty efficient hosting platform as far as memory is concerned. One of the great feature of Passenger is that you can configure it to automatically shut down your Rails application if it is idle for a certain period of time. Doing this obviously exerts a cost then on the next hit, but this may be an acceptable tradeoff for a server hosting many low-traffic sites. The configuration option is RailsPoolIdleTime and there is more information on this in the user guide.ConclusionObviously my introduction here doesn’t go in-depth into performance and ability of Passenger to scale. Time will tell as people begin using this whether it is a viable solution for Rails hosting, but for me installing this and getting it to work was dirt simple, at least compared to the mod_proxy_balancer setup with mongrel clusters I have used in the past. I’m not quite ready to actually host my sites using this but I’ll definitely be keeping my eye on this – it could be a major step forward in the proliferation of Rails hosting.

Author: "benhughes" Tags: "Rails General, Rails Tools"
Comments Send by mail Print  Save  Delicious 
Date: Tuesday, 01 Apr 2008 23:12

I am convinced this is the next big thing: Cobol on Cogs.  Definitely the future of web development.  As of today I renounce Ruby on Rails and all it stands for!

Author: "benhughes" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Wednesday, 19 Mar 2008 21:14

Today I deployed a major update to my Jazz object model which implements a full REST web interface that is currently accessible through a web browser. Visit http://www.jazztoolbox.com/ for the RDocs - there are plenty of examples at the bottom of the index file, or you can try this immediately:

http://www.jazztoolbox.com/chords.xml

Some fairly complex relationships can be explored in this manner just using your web browser (displaying XML). Note that I still do not have a whole lot of data in here; all the data is just my personal knowledge of Jazz theory. Eventually I will consult a theory reference and develop the database of jazz more thoroughly.

Author: "benhughes" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Tuesday, 11 Mar 2008 20:35

Something I constantly find myself doing is checking to see if a value is blank, and returning something else if it is, otherwise the object itself:

birthday.blank? ? '0000-00-00' : birthday

I started thinking about how I could possibly eliminate the need for all these ternary operators, and came up with this:

class Object
  def or_if_blank(value)
    self.respond_to?(:blank) && self.blank? ? value : self
  end
end

Now we can do something like this:

birthday.or_if_blank('0000-00-00')

You could do something similar for nil, though a more general Ruby idiom is to just use the || operator, which does not work for blank.

On another note, if any of you are used to appending a “if object.respond_to?(:method)” predicate, check out this technique using try.

Author: "benhughes" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Monday, 25 Feb 2008 17:30

As a (wannabe) Jazz pianist, I’ve always had a strong interest in Jazz theory not only from a practical you-need-this-to-play standpoint but also a theoretical standpoint. At it’s core, music theory is all about a 0 - 11 number system where each number represents a pitch, with the added complication of letters (which makes Eb theoretically different from D#). Everything in music is based on this basic number system: scales and chords are simply sequences of these numbers. Changing key in a scale or chord mathematically is adding some integer to all of the index values and doing modulo 12. Changing modes within a scale simple involves a position shift of the sequence.

Last week I began exploring the idea of developing some sort of computerized object model to capture these musical theory concepts. As a pianist, knowing theory is extremely important and voicing chords can become quite complex, yet there is sanity in the complexity - a harmony of mathematical precision. Today I introduce “Jazz Toolbox”, the future front-end for which will be located at JazzToolbox.com. Right now I have only developed the back-end object model and calculation engine, which is definitely the foundation of the project. I’ve also written up extensive documentation. Here’s an introduction to the project straight out of my README file:

Jazz Toolbox

Jazz Toolbox is an online Jazz utility driven by a full object-relational and REST model of
concepts in Jazz theory, establishing relationships between chords and scales, and much more.
The web interface is a fully Ajaxified Web 2.0 interface towards exploring these relationships and
answering questions about the jazz science. The REST interface exposes the underlying data model
and relationships to other developers wishing to use Jazz Toolbox as a source for their own web
applications.

Architecture Overview

The core of Jazz Toolbox is a full Ruby object model representing concepts of Jazz theory,
distilled to their most basic concepts and architected in a very abstract manner. The system
is data-centric and all “rules” (for example, the tones in a C7 chord) in theory are
self-contained in the database.

All chord/scale/mode/etc. definitions are stored as a mathematical system (sequences of numbers)
which are then used to perform calculations. For example, putting some chord in a different key
is a matter of adding a semitone delta and doing modulo 12.

While there are currently many chord calculators in existance, to my knowledge this project is the
first one that attempts to fully represent the entirety of Jazz theory as a mathmetical/computational
system exposed through an elegant object model.

Full Documentation

I’ve published the full RDocs which are available here and are very complete.

Examples

Any musician/programmer will appreciate these examples; far more are available in the rdocs:

 Chord['Ebmaj7'].notes
 # => ['Eb', 'G', 'Bb', 'D']
 # Or specify key context with chained methods like this...
 Chord['maj7'].in_key_of('Eb').notes

 Chord['Bmaj7#11'].notes
 # => ['B', 'D#', 'F#', 'A#', 'E#']
 # Note E# - Correct theoretic value for this chord, not F

 Chord['Falt'].notes
 Chord['F7b9#9'].notes
 # => ['F', 'A', 'Eb', 'Gb', 'G#', 'C#']

 Scale['Major'].in_key_of('Eb').modes['Dorian'].notes
 # => ['F', 'G', 'Ab', 'Bb', 'C', 'D', 'Eb']

 Scale['Melodic Minor']['Lydian Dominant'].notes
 # => ['F', 'G', 'A', 'B', 'C', 'D', 'Eb']

 Scale['Major']['Dorian'].chords.symbols
 # => ['min7', 'min6']

 Chord['Amin7'].modes.names
 # => ['A Dorian']

 Scale['Major'][4].chords.symbols
 # => ['maj7#11']

This is definately still a work in progress though it has the potential to become very powerful. I have high ambitions for the front-end web interface for this as well as it could become a valuable tool for Jazz musicians and others trying to nagivate the complex roads of jazz…

Author: "benhughes" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Thursday, 21 Feb 2008 17:42

Occassionally I’ll decide to create some structured data in a migration by issuing create statements against my model classes. In a project I’m currently working on, I had to do this several levels deep. Rather than using temporary variables to create the sub items and so-on, all in a lexically flat structure, I came up with this simple one-liner:

def self.with(o); yield o; end

Doing this now allows me to issue those creates with nested data as a series of nested blocks, which is looks much better. For example:

with ChordQuality.create(:name => 'Major', :code => 'MAJ') do |q|
  with q.chords.create(:name => 'Major Triad') do |c|
    c.chord_symbols.create(:name => 'maj')
    c.chord_symbols.create(:name => 'M', :case_sensitive => true)
  end
  with q.chords.create(:name => 'Major 7') do |c|
    c.chord_symbols.create(:name => 'maj7')
    c.chord_symbols.create(:name => 'M7', :case_sensitive => true)
    with c.children.create(:name => 'Major 7 #11') do |cc|
      cc.chord_symbols.create(:name => 'maj7#11')
      cc.chord_symbols.create(:name => 'M7#11')
      cc.chord_symbols.create(:name => 'lyd')
      cc.chord_symbols.create(:name => 'lydian')
    end
  end

  with q.chords.create(:name => 'Major 6') do |c|
    c.chord_symbols.create(:name => 'maj6')
    c.chord_symbols.create(:name => 'M6', :case_sensitive => true)
  end
end

Oh, the beauty of Ruby code blocks!

Author: "benhughes" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Thursday, 07 Feb 2008 14:15

Since working with Ruby and other dynamic languages, I’ve thought a lot about the differences between statically-typed and dynamically-typed languages and what makes them different. Statically-typed languages guarantee some level of confidence of workability — but this comes at a huge cost of flexibility, and more importantly overlaps with software testing, not making efficient use of the concept of testing.

Software testing can be used to make up for some of the lost confidence resulting from dynamic typing, yet since they must be done regardless, the outcome is suboptimal with static languages - there is an overlap between the confidence generated from static typing and the confidence generated from the test suite. With dynamic languages there is much less overlap: the test suite makes up for the confidence lost from dynamic typing, yet is also there to ensure the software works as expected.

Author: "benhughes" Tags: "Ruby Evangelism, Ruby Language"
Comments Send by mail Print  Save  Delicious 
Date: Saturday, 02 Feb 2008 20:35

ActiveRecord::Base exposes a great way of keeping access control DRY. A very common paradigm in web application development is showing “all” of something to administrators but only only “active” of something to regular users/visitors. In non-ORM PHP you might do something like like this in each SQL statement:

$sql  = "SELECT * FROM entries WHERE type = 1 ";
$sql .= (!$is_admin ? "AND active = 1" : "");

This isn’t a very well-architected approach since this type of tacking onto the SQL string would have to be done in any statement that involved this table, for all of your “actions” like show, edit, and index. It tightly couples this particularly piece of add-on logic to your base code. In Rails we can scope out this functionality to a “scope_access” method in our controller like so:

class EntriesController < ApplicationController
  around_filter :scope_access

  # (Action Methods)

  protected

  def scope_access
    unless current_user && current_user.is_admin?
      Entry.send(:with_scope, :find => {:conditions => 'active = 1'}) do
        yield
      end
    else
      yield
    end
  end
end

We are declaring an around_filter which uses with_scope if the current user is an admin, otherwise it will do so without scope. This is an excellent example of how Rails allows you to architect your code to be very elegant. Note that with_method is now a protected method on ActiveRecord::Base hence our need to use ClassName.send.

The with_scope method is actually useful for many other purposes including running many but similar find statements. Aside from finders, this can actually scope attributes on create and more. I’d highly recommend you check it out in the Rails documentation and start making extensive use of it.

Author: "benhughes" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Saturday, 02 Feb 2008 20:06

Antagonistic attitudes towards Ruby and in particular Ruby on Rails abound. Many web developers feel uneasy about the rise of a strange new framework that is attracting disciples daily. I’ve casually chatted with a few people who have negative attitudes about Ruby and the most striking aspect about everyone I’ve spoken with is that after prodding a bit at their understanding and experience level with Ruby I find they only have a surface-level understanding of Rails and no experience whatsoever. I have not once found someone who was well-versed in both Ruby on Rails (as in.. has actually built an application using it) and in any of the other number of web technologies out there, who was not at the very least appreciative about Rails and optimistic about its future.

What I’m trying to get at here is that to appreciate Ruby you have to know Ruby, and know it well. A surface-level examination of Rails by myself over one year ago left me in the same ignorant state that many Ruby antagonists are at right now, complaining about Ruby’s ability to scale and the restrictive nature the Rails framework involves. Even reading a few chapters out of the Agile book might leave one with this characterization. Yet the more I began to understand Rails and even more importantly the dynamic Ruby programming language, the more positive my attitudes towards Rails were.

It’s interesting that I find this particular understanding imbalance even more widespread and frustrating in economics: to appreciate the free market, you have to understand the free market. So few people truly understand economics and as a result their arguments are ripe with economic fallacies and mischaracterizations of fact. Economists on average believe that the free market works significantly better than non-economists. This isn’t a conspiracy: it’s because they actually understand economics.

There will always be people in any field that attack something they don’t understand for whatever reason. Those making arguments against Rails at least owe it to their opponents to actually understand what they are talking about. I find such is rarely the case.

Author: "benhughes" Tags: "Ruby Evangelism"
Comments Send by mail Print  Save  Delicious 
Next page
» You can also retrieve older items : Read
» © All content and copyrights belong to their respective authors.«
» © FeedShow - Online RSS Feeds Reader