What's New in Edge Rails: Your DB Adapter May Have Left the Building

Posted by ryan
at 10:36 AM on Sunday, September 30, 2007

If your Rails app happens to be running against anything but a MySQL, PostgreSQL or SQLite database and you’re on Edge Rails (or are headed to Rails 2.0) then you’re going to need to make sure you have the correct gems installed on your machine. As of now the database adapters for these databases have been pulled out of the core Rails distribution and are available as gems. One of these should work for you if you rely on one of the affected databases:

1
2
3
4
5
6
gem install activerecord-oracle-adapter
gem install activerecord-sqlserver-adapter
gem install activerecord-firebird-adapter
gem install activerecord-frontbase-adapter
gem install activerecord-openbase-adapter
gem install activerecord-sybase-adapter

tags: ruby, rubyonrails

What's New in Edge Rails: Logging Gets a Little Snappier

Posted by ryan
at 7:55 AM on Tuesday, September 25, 2007

Edge Rails just got a new, buffered logger that will, apparently, make logging in Rails a little snappier.

This new logger is now the default, though you can change it back to the original logger in your environment.rb with:


config.logger = Logger.new('/path/to/log', Logger::DEBUG)

Though I’m not sure why you’d want to do that…

tags: ruby, rubyonrails

What's New in Edge Rails: Better Cross-Site Request Forging Prevention

Posted by ryan
at 8:50 AM on Monday, September 24, 2007

Hot on the heels of the in-depth look at Rails security options comes the addition of the CsrfKiller plugin into rails core.

The CsrfKiller plugin adds a unique session token field to all forms that is checked on every non-GET request. This ensures that the request received is in fact coming from the session of the authorized user (check out wikipedia’s CSRF article if you need more details on the technique).

All you need to do to enable this protection is to add a protect_from_forgery statement in your controller that takes the familiar :except or :only option along with salt to use when generating the unique token:

And now this is the default functionality. No need to specify anything if you want the default behavior. You can still override as in the following examples, however.

1
2
3
4
5
class PostsController < ApplicationController

  protect_from_forgery :secret => '2kdjnaLI8', :only => [:update, :delete, :create]
  ...
end

If you’re already using edge Rails’ default cookie session store then you don’t have to specify the :secret key.


protect_from_forgery :only => [:update, :delete, :create]

If you’re not on a cookie session store you can also change the digest method used to generate the unique token (the default is ‘SHA1’).


  protect_from_forgery :secret => '2kaienna9ea90djnaLI8', :digest => 'MD5'

If a request comes in that doesn’t match the request forgery protection token for the current session then an ActionController::InvalidAuthenticityToken exception will be thrown. Perhaps a good place to try out the new exception handling syntax ?

Caveats: The request forgery protection only kicks in in the following scenarios:
  • Non-GET requests, so make sure the only requests that modify state are your PUT/POST/DELETE requests.
  • On html and ajax requests. Override verifiable_request_format? if you want to expand that.

And what to do if you want to disable CSRF protection? Just add this to whatever controllers you don’t want to be affected:


skip_before_filter :verify_authenticity_token

And if you want to disable this site-wide, just add this to application.rb:


self.allow_forgery_protection = false

tags: ruby, rubyonrails

What's New in Edge Rails: Better Exception Handling

Posted by ryan
at 8:45 AM on Monday, September 24, 2007

It’s a common pattern to redirect the user to, or render specific pages for different types of exceptions that are thrown in your application. Prior to this changeset this usually involved overloading the rescue_action_in_public method of your controllers:

1
2
3
4
5
6
7
8
9
class PostsController < ApplicationController
  def rescue_action_in_public(exception)
    case(exception)
      when ActiveRecord::RecordNotFound then render :file => '/bad_record'
      when NoMethodError then render :file => '/no_method'
      else render :file => '/error'
    end
  end
end

It’s easy to see that this can quickly grow to be an ugly mass of a case or if/else statement.

Now we’ve got a much cleaner way to map exceptions to handlers with the new rescue_from support. rescue_from maps an exception type directly to a handler method name for a very concise and direct way of dealing with exceptions:

1
2
3
4
5
6
7
8
9
10
class PostsController < ApplicationController

  # Declare exception to handler methods
  rescue_from ActiveRecord::RecordNotFound, :with => :bad_record
  rescue_from NoMethodError, :with => :show_error

  def bad_record; render :file => '/bad_record'; end
  def show_error(exception); render :text => exception.message; end

end

Note that the exception handler methods can be either no-arg methods or take the exception in question as an argument (as in show_error above).

You can also use a block or proc to specify exception handling in rescue_from:

1
2
3
4
5
6
7
class PostsController < ApplicationController

  # Declare exception to handler methods
  rescue_from(ActiveRecord::RecordNotFound) { |e| render :file => '/bad_record' }
  rescue_from NoMethodError, :with => proc { |e| render :text => e.message }

end

tags: ruby, rubyonrails

What's New in Edge Rails: Specify Plugin Load Ordering

Posted by ryan
at 8:10 AM on Monday, September 24, 2007

You’ve always been able to specify exactly which plugins you want to be loaded up with your Rails app, instead of haphazardly loading everything in vendor/plugins with this little snippet that you may or may not see in your environment.rb file:

1
2
# Only load the plugins named here, by default all plugins in vendor/plugins are loaded 
config.plugins = %W( exception_notification ssl_requirement ) 

The problem with this is that while you can explicitly specify which plugins you want loaded and in what order, it becomes quite tedious to list out every plugin when you only care about the load order of a select few.

Well, this has been taken care of with the :all symbol you can now use in your config.plugin list to denote all other plugins not explicitly listed:


config.plugins = [ :exception_notification, :ssl_requirement, :all ] 

This gives you finer-grain control over your plugin load order. You can even use :all in the middle of your load order if you want to push some plugins to the back of the line:


config.plugins = [ :exception_notification, :all, :ssl_requirement ] 

tags: ruby, rubyonrails

And Then There Was One

Posted by ryan
at 2:30 PM on Wednesday, September 05, 2007

About four months ago I took a leap of faith and decided to join the rest of you who enjoy the flexibility of self-employment and the ability to work with the technology you actually enjoy and went out on my own. Y|Factorial, LLC was born after a lot of thought about where I was, where I wanted to go and what I want to do – and the answer was to create my own Ruby software development shop.

I definitely have very strong feelings about what Y|Factorial stands for, how it goes about its business and how it will manage its employees. Much of it is still a work in progress, but it’s my intent to be as painfully transparent about this maturation process as possible over on The Naked Company blog. I’m sure I’ll make a few mistakes, fall on my face a few times, and even anger some – but the hope is that, overall, it will be of some benefit.

So, take a peek, laugh at my naivety and maybe even drop me a line if you’re looking for development help.

Cheers.

tags: Y Factorial, ruby, rubyonrails

What's New in Edge Rails: Validations Now :allow_blank

Posted by ryan
at 7:40 AM on Wednesday, September 05, 2007

This is a tiny update, but one worth mentioning. The various activerecord validation methods now accept an :allow_blank option that will let validation pass if the value is nil or an empty string.

1
2
3
4
5
6
class Post < ActiveRecord::Base
  validates_length_of :meta, :maximum => 3, :allow_blank => true
end

p = Post.new(:meta => "")
p.valid?  #=> true

Hardly earth-shattering, but convenient and a nice compliment to :allow_nil.

tags: ruby, rubyonrails