Life on Edge Rails

Posted by Marc Love
on Thursday, May 31

Date#change

Date now has #change and works just like Time#change. So now we can do:
next_bill_date = Date.today.change( :month => Date.today.month + 1, :day => 15)

All controller names pluralized

map.resource will now map to a pluralized controller name by default:
map.resource :account  # now maps to:
AccountsController < ApplicationController

Where this makes even more sense to me is in this situation which I brought up in a post on the rubyonrails-core mailing list . Let’s say I have products which each has_one manufacturer. I want to be able to control those manufacturers both within the context of their association with the products and separately on their own. The way it used to be:

map.resources :products, :has_one => :manufacturer #=> ManufacturerController
map.resources :manufacturers #=> ManufacturersController

The first mapping would look for a ManufacturerController because :has_one generates a singleton resource. But the second mapping would look for a ManufacturersController. Regardless of the context, I’m probably going to control my manufacturers resource the same way. So now all controllers are by default plural, whether its coming from map:resource, map.resources, :has_one, or :has_many.

map.resources :products, :has_one => :manufacturer #=> ManufacturersController
map.resources :manufacturers #=> ManufacturersController

with_scope and with_exclusive_scope are now protected

DHH has followed through on his promise to make with_scope a protected method and with_exclusive_scope has come along for the ride.

Ruby Measurements

Posted by Marc Love
on Thursday, May 31

Here’s something I’ve been working on…

Measurement.new(6,"inches") == 6.inches

2.feet + 6.inches # => == Measurement.new(2.5, "feet")
6.5.feet - 18.inches # => == Measurement.new(5, "feet")
2.feet * 4 # => == Measurement.new(8, "feet")
4.feet / 2 # => == Measurement.new(2, "feet")
4.feet / 2.feet # => == 2

2.inches > 2.centimeters #=> true
2.inches >= 2.centimeters #=> true
2.inches == 5.08.centimeters #=> true
5.inches.between?(3.inches, 6.inches) #=> true

More to come soon…

Association-generated methods quick reference

Posted by Marc Love
on Wednesday, May 30

One of the documentation patches I submitted last night was just accepted into the core. It’s a quick reference table of the methods that are auto-generated when an association is created.

# ===Singular associations (one-to-one)
#                                     |            |  belongs_to  |
#   generated methods                 | belongs_to | :polymorphic | has_one
#   ----------------------------------+------------+--------------+---------
#   #other                            |     X      |      X       |    X
#   #other=(other)                    |     X      |      X       |    X
#   #build_other(attributes={})       |     X      |              |    X
#   #create_other(attributes={})      |     X      |              |    X
#   #other.create!(attributes={})     |            |              |    X
#   #other.nil?                       |     X      |      X       |    
# ===Collection associations (one-to-many / many-to-many)
#                                     |       |          | has_many
#   generated methods                 | habtm | has_many | :through  
#   ----------------------------------+-------+----------+----------
#   #others                           |   X   |    X     |    X
#   #others=(other,other,...)         |   X   |    X     |    
#   #other_ids                        |   X   |    X     |    
#   #other_ids=(id,id,...)            |   X   |    X     |    
#   #others<<                         |   X   |    X     |    X
#   #others.push                      |   X   |    X     |    X
#   #others.concat                    |   X   |    X     |    X
#   #others.build(attributes={})      |   X   |    X     |    X
#   #others.create(attributes={})     |   X   |    X     |    
#   #others.create!(attributes={})    |   X   |    X     |    X
#   #others.size                      |   X   |    X     |    
#   #others.length                    |   X   |    X     |    
#   #others.count                     |       |    X     |    
#   #others.sum(args*,&block)         |   X   |    X     |    X
#   #others.empty?                    |   X   |    X     |    
#   #others.clear                     |   X   |    X     |    
#   #others.delete(other,other,...)   |   X   |    X     |    X
#   #others.delete_all                |   X   |    X     |    
#   #others.destroy_all               |   X   |    X     |    
#   #others.find(*args)               |   X   |    X     |    X
#   #others.find_first                |   X   |          |    
#   #others.uniq                      |   X   |    X     |    
#   #others.reset                     |   X   |    X     |    X