Good notes posted by james
RSS feedhaml, an alternative to ERb
Want something nicer looking (and currently, faster!) than using ERb for your views? Have a look at haml (and it’s companion, sass, for stylesheets). It will make you feel all fuzzy on the inside, I promise :P.
ERb example
<div id="profile"> <div class="left column"> <div id="date"><%= print_date %></div> <div id="address"><%= current_user.address %></div> </div> </div>
haml equivalent
#profile .left.column #date= print_date #address= current_user.address
Shifting to haml from ERb feels strange at first, but after about 20 minutes it starts to feel nice. A little longer and you’ll really start to notice your productivity (and of course, happiness) increase! :). I’ve starting shifting all new projects developed at our work office over to using haml (and sass), it’s been fantastic!
At first I came across a few things that I couldn’t do in haml, though every time a quick read of the overview doc page would show me a simple syntax for overcoming that issue! :) (which out of interest, is located here: http://haml.hamptoncatlin.com/docs/rdoc/classes/Haml.html)
Give the tutorial a shot if you’re interested: http://haml.hamptoncatlin.com/tutorial
link_to with block (Edge Rails)
New ability in Edge Rails to use link_to called with a block, e.g. The following is a view example:
<% link_to some_path do %> <strong>Awesome link</strong> -- it's pretty awesome <% end %>
This change was made in: http://github.com/rails/rails/commit/8190bce8bc7249b7b9f3680195336eb3ca9508ee
Patch in yourself, or likewise you can use the following snippet (which is the new link_to method with modifications [there are also Array extensions on edge to provide .second, .third etc which aren’t present]).
url_helper_extensions.rb
module ActionView module Helpers module UrlHelper def link_to(*args, &block) if block_given? options = args.first || {} html_options = args[1] concat(link_to(capture(&block), options, html_options)) else name = args.first options = args[1] || {} html_options = args[2] url = case options when String options when :back @controller.request.env["HTTP_REFERER"] || 'javascript:history.back()' else self.url_for(options) end if html_options html_options = html_options.stringify_keys href = html_options['href'] convert_options_to_javascript!(html_options, url) tag_options = tag_options(html_options) else tag_options = nil end href_attr = "href=\"#{url}\"" unless href "<a #{href_attr}#{tag_options}>#{name || url}</a>" end end end end end
automatically generate scopes for model states
or better known as “throw on some more tasty meta-programming” :). Given an example of a model which has a state (String) which must from a set of defined values, e.g. pending, approved, denied.
class User < ActiveRecord::Base STATES = [ 'pending', 'approved', 'denied' ] validates_inclusion_of :state, :in => STATES # Define a named scope for each state in STATES STATES.each { |s| named_scope s, :conditions => { :state => s } } end
This automatically defines a named_scope for each of the model states without having to define a named_scope manually for each state (nice and DRY).
Easy and effective admin authentication
Great for use within an AdminController (in which all other administrative controllers inherit from AdminController).
class AdminController < ApplicationController before_filter :authenticate def authenticate authenticate_or_request_with_http_basic('Administration') do |username, password| username == 'admin' && password == 'password' end end end
perform update_all scoped within a has_many collection
For example: having two models, User and Message (user has_many messages, each message has a boolean flag called ‘read’). You want to mark all messages as read for a particular user.
Mark all messages as read for a particular user
Message.update_all({:read => true}, {:id => user.messages})
Rails 2.1 migrations
Things to take note of are the lack of ‘column spam’, which didn’t convey much semantic meaning. Also the combination of multiple fields per line with the same type.
references is also a nice helper to convey relationship information (t.references :role is equivilant to t.integer :role_id). references also takes another parameters, see the method for more details.
code
class CreateUsers < ActiveRecord::Migration def self.up create_table :users do |t| t.string :first_name, :last_name, :email t.text :address t.date :date_of_birth t.references :role t.timestamps end add_index :users, :email end def self.down drop_table :users end end
Better slug generation (essentially a to_param replacement)
Monkey Patching String
class String def slugify returning self.downcase.gsub(/'/, '').gsub(/[^a-z0-9]+/, '-') do |slug| slug.chop! if slug.last == '-' end end end
In a model, or wherever
def to_param # Don't need the id here if we're looking up the model by the stored slug. "#{id} #{title}".slugify end