This is another edition of Rails Core Weekly, affectionately known as
RCW. A much nicer pre-web 3.0 version is available from the following
url :
http://www.pinupgeek.com/articles/category/rails-core-weekly-news
We have an Atom/RSS feed available there as well.
Rails Core Weekly summarizes the rails-core mailing list, a list
dedicated to Ruby on Rails internals and its development. RCW is
brought to you by Rodney Ramdas and proofread by the good people of
The Caboose (http://blog.caboo.se/) for accuracy.
Enjoy.
Rails Core Weekly June 19 - July 2 2006
=========================================
I missed a week. I''m sorry. I was at Railsconf 2006 and there was just
too much going on to write an RCW. Also the week before RCW was pretty
boring (Rails Core-wise). But things are better now. Lots of stuff
going on. Read on !
Threads
-------
[ thread: http://www.ruby-forum.com/topic/69959#new ]
Jeremy Kemper adds pessimistic locking to Active Record with the :lock
option. Pessimistic locking does row level locking for you. In
SQL-speak, it provides ''select blah from bluh for update''.
>From Jeremy''s documentation:
# Example for find with a lock. Imagine two concurrent transactions:
# each will read person.visits == 2, add 1 to it, and save, resulting
# in two saves of person.visits = 3. By locking the row, the second
# transaction has to wait until the first is finished; we get the
# expected person.visits == 4.
# Person.transaction do
# person = Person.find(1, :lock => true)
# person.visits += 1
# person.save!
# end
The Oracle adapter doesn''t like this one bit and dies horribly with an
ORA-02014. Could be due to Active Record using the oracle rownum
pseudo-column to mimic mysql''s LIMIT behavior. However, rownum is not
allowed in Oracle''s FOR UPDATE statements.
[ thread: http://www.ruby-forum.com/topic/68411#new ]
Solomon White proudly presents a RegexpError: regular expression too
big which seems to come from the new routing code. Jamis reports it
fixed only a couple of hours later. Wilson Bilkovich thinks he''s
running into related problems causing memory leaks and posts his test
scenario. Do try this at home and not on your production servers:
while true; do /usr/sbin/ab -n 1000 -c 30 http://example.com/
2>/dev/null | grep quest.*mean ; echo -- ; done
When he reverted to rev 4358 things got better again.
[ thread: http://www.ruby-forum.com/topic/70546#new ]
A question was popped whether railties patches need tests. Kevin Clark
suggests using a mock, or something like FlexMock.
[ thread: http://www.ruby-forum.com/topic/68613#new ]
Blair needs reload-able modules and wrote a patch that does that for
you (http://dev.rubyonrails.org/ticket/5329). Trevor Squires tips
everyone of that you can put a require_dependency ''my_module''
just
before an include MyModule call to make most of the pain go away.
[ thread: http://www.ruby-forum.com/topic/70581#new ]
Hampton reports tests are broken since some Enumerable changes (see
below "New Features"). Coda Hale replies saying Enumerable#sum was
overriding AR::Calculations#sum and that he provided a patch that
calls the correct #sum for calculations.
(http://dev.rubyonrails.org/ticket/5500)
[ thread: http://www.ruby-forum.com/topic/70906#new ]
A patch that fixes some issues with :expects is submitted and
committed promptly: http://dev.rubyonrails.org/ticket/4720. This seems
to trigger a couple of reminder threads on various patches submitted
but not committed. Question arise again on the whole submit->commit
process.
[ thread:http://www.ruby-forum.com/topic/71241#new ]
Peter Michaux asks how to go about learning about Active Records
internals. He went to David Black''s book ( Ruby for Rails) but that
doesn''t seem to hold the detail he wants. Hampton replies that
he''s
been playing with the idea to do a book on exactly that subject.
(Everyone should now mail Hampton to ask when it''s done). Marcel
Molina Jr. gives Peter the advise to take a top down approach and
start with studying ActiveRecord::Base#find and then work you way down
from there. If anyone does please make notes and put them in a Rails
Hacking Guide. Thanks.
[ thread: http://www.ruby-forum.com/topic/70579#new ]
Coda Hale submits a patch that makes eagerly loaded associations
respect :order He offhandedly posts the patch but then comes back to
give an excellent explanation of what he''s done and why. You have to
read it, follow the thread link. However Coda Hale takes a
controversial stance on the default order of SQL result sets when no
explicit order is given. He makes it default to the primary key order.
Michael Glaesemann spots this assumption and claims no such order
exists. Pretty interesting thread.
New Features
--------------
Arguably, the most important fix this last 2 weeks:
http://dev.rubyonrails.org/ticket/4473
Equally important is that Edge Rails now ships with default Mongrel
support. If you don''t know about Mongrel (what?) check out
http://mongrel.rubyforge.org/ In fact Mongrel is preferred over
lighttpd: http://dev.rubyonrails.org/changeset/4507 Jeremy makes it
work in win32 as well (http://dev.rubyonrails.org/changeset/4504)
As said in Threads, you can now do Pessimistic Locking. See
description above but be aware on Oracle :
http://dev.rubyonrails.org/changeset/4462
rails -v or rails --version is now documented:
http://dev.rubyonrails.org/changeset/4471
Sam Stephenson added a find_or_initalize_by_x similar to
find_or_create_x except that initialize does not save the record just
yet. From his documentation:
# # No ''Winter'' tag exists
# winter = Tag.find_or_initialize_by_name("Winter")
# winter.new_record? # true
Another example is found in the test he wrote. This uses 2 attributes
to search on:
def test_find_or_initialize_from_two_attributes
another = Topic.find_or_initialize_by_title_and_author_name("Another
topic","John")
assert_equal "Another topic", another.title
assert_equal "John", another.author_name
assert another.new_record?
end
That''s pretty useful ! His patch is quite nice I think as well, well
worth studying (uses ActiveRecord::Base#send):
http://dev.rubyonrails.org/changeset/4473
The very useful Module#alias_method_chain is further enhanced by
Jeremy Kemper to allow preservation of method punctuation. Jeremy
explains:
alias_method_chain :foo?, :feature
is equivalent to
alias_method :foo_without_feature?, :foo?
alias_method :foo?, :foo_without_feature?
If you''re unfamiliar with this method read
http://weblog.rubyonrails.org/2006/4/26/new-in-rails-module-alias_method_chain.
You might never use it since it''s internal to Rails but study it
nevertheless to sharpen your Ruby-mind.
Also, DHH adds Enumerable#sum for calculating a sum from the elements
(incidently shadowing AssociationCollection#sum but that is fixed
quickly enough). Also Jeremy makes it a bit better by making it
block-less Example:
payments.sum { |p| p.price * p.tax_rate }
payments.sum(&:price)
or simply block-less:
[1,2,3].sum # => 6
DHH explains this is instead of
payments.inject(0) { |sum, p| sum + p.price }
In fact the implementation of #sum is virtually the same:
inject(0) { |sum, element| sum + yield(element) }
Quickly thereafter Nick Seckar adds index_by to Enumerable which
turns an Enumerable into a hash like so:
people.index_by(&:login)
So this hash
{5 => payments[0], 15 => payments[1], 10 => payments[2]}
is pretty much equal to
payments.index_by(&:price)
but certainly a lot prettier.
Then of course Active Resource is added
(http://dev.rubyonrails.org/changeset/4492) Lots have been said about
Active Resource and there seem to be quite a debate raging on in the
blogosphere. For a great explanation of Active Resource in general go
here:
http://jimonwebgames.com/articles/2006/06/26/dont-say-crud-say-fucd
(I like that one because it speaks of Edgar Codd, who together with
Chris Date are the granddaddies of the relational model)
For a great introduction to Active Resource itself go to Ryan''s blog:
http://www.ryandaigle.com/articles/2006/06/30/whats-new-in-edge-rails-activeresource-is-here
and for a more ''philosophical'' design-issues and applicability
view go to
http://blog.hasmanythrough.com/articles/2006/06/30/cruddy-searches
Coda is reacting in a different way:
http://blog.codahale.com/2006/07/01/crud-is-not-the-only-user-interaction-metaphor-thank-you/
. All well worth reading.
Nick adds a route_name_path method to return only the path for a
named routes. For example, map.person will add person_path. Seems
innocent enough but it''s pretty nifty. You pass :only_path => true
to
a named route to get just that. Read about it
here:http://dev.rubyonrails.org/changeset/4518
Finally, in the stable branch shortly after the security release
1.1.3, a follow up release 1.1.4 is issued. You are strongly advised
to upgrade when applicable.
That''s it for this week !
--
Rodney
http://www.pinupgeek.com
http://www.dutchrailers.org