Notes posted to Ruby on Rails
RSS feed
takes ActiveRecord object as an arg as well
One undocumented feature, you can do this:
person = Person.first Person.exists?(person) # => returns true
This came in handy for me when I needed to see if something belonged to a particular scope.
scope = "created_rails" person = Person.find_by_name "dhh" Person.send(scope).exists?(person) # => returns true
Obviously this relies on you having a named_scope in your Person model called “created_rails”.

Don't forget about as
:as is a good but poorly document argument to rendering a collection:
<%= render :partial => 'some_partial', :collection => an_array, :as => :better_name -%>
Which will give you each element of an_array in the partial in a local variable named better_name not some_partial.

Set hour and/or minutes
To set the hour and/or the minutes, you can use:
<%= f.datetime_select(:offer_end, :default => { :hour => 23, :minute => 59 }) %>

Undocumented :inverse_of option
Support for the :inverse_of option was backported to 2.3.6+.
Here’s the description from the original commit: http://github.com/rails/rails/commit/ccea98389abbf150b886c9f964b1def47f00f237
You can now add an :inverse_of option to has_one, has_many and belongs_to associations. This is best described with an example:
class Man < ActiveRecord::Base has_one :face, :inverse_of => :man end class Face < ActiveRecord::Base belongs_to :man, :inverse_of => :face end m = Man.first f = m.face
Without :inverse_of m and f.man would be different instances of the same object (f.man being pulled from the database again). With these new :inverse_of options m and f.man are the same in memory instance.
Currently :inverse_of supports has_one and has_many (but not the :through variants) associations. It also supplies inverse support for belongs_to associations where the inverse is a has_one and it’s not a polymorphic.

Undocumented :inverse_of option
Support for the :inverse_of option was backported to 2.3.6+.
Here’s the description from the original commit: http://github.com/rails/rails/commit/ccea98389abbf150b886c9f964b1def47f00f237
You can now add an :inverse_of option to has_one, has_many and belongs_to associations. This is best described with an example:
class Man < ActiveRecord::Base has_one :face, :inverse_of => :man end class Face < ActiveRecord::Base belongs_to :man, :inverse_of => :face end m = Man.first f = m.face
Without :inverse_of m and f.man would be different instances of the same object (f.man being pulled from the database again). With these new :inverse_of options m and f.man are the same in memory instance.
Currently :inverse_of supports has_one and has_many (but not the :through variants) associations. It also supplies inverse support for belongs_to associations where the inverse is a has_one and it’s not a polymorphic.

Undocumented :inverse_of option
Support for the :inverse_of option was backported to 2.3.6+.
Here’s the description from the original commit: http://github.com/rails/rails/commit/ccea98389abbf150b886c9f964b1def47f00f237
You can now add an :inverse_of option to has_one, has_many and belongs_to associations. This is best described with an example:
class Man < ActiveRecord::Base has_one :face, :inverse_of => :man end class Face < ActiveRecord::Base belongs_to :man, :inverse_of => :face end m = Man.first f = m.face
Without :inverse_of m and f.man would be different instances of the same object (f.man being pulled from the database again). With these new :inverse_of options m and f.man are the same in memory instance.
Currently :inverse_of supports has_one and has_many (but not the :through variants) associations. It also supplies inverse support for belongs_to associations where the inverse is a has_one and it’s not a polymorphic.

Validating presence of parent in child
When creating a parent and its children using nested attributes, you can use the :inverse_of option on the association to correctly set the parent back references:
class Parent < ActiveRecord::Base has_many :children, :inverse_of => :parent accepts_nested_attributes_for :children end class Child < ActiveRecord::Base belongs_to :parent validates_presence_of :parent end


update_all and serialized attributes
If you use update_all to change an attribute marked as serialized ( using ActiveRecord::Base.serialize ), you need to call to_yaml yourself:
User.update_all({ :preferences => { :first_name => 'John', :last_name => 'Doe' }.to_yaml })

add_to_base in Rails 3
use
model_instance.errors[:base] << "Msg"
instead of depracated
model_instance.errors.add_to_base("Msg")
for Rails 3

Depracated add_to_base
use
model_instance.errors[:base] << "Msg"
instead of depracated
model_instance.errors.add_to_base("Msg")
for Rails 3

Confusing log output
If you do a single Rails.cache.read('my_key'), your will usually see in your log something like
Cache read: my_key Cache read: my_key Cache write: my_key
Don’t worry about this.
What happens here is this: Before going to memcached, rails will first ask a local MemoryStore cache (which is responsible for the first and third line in the log), before falling through to memcached. This local cache is destroyed after each request.
Source is in activesupport/lib/active_support/cache/strategy/local_cache.rb.

In Rails3 use "unscoped" instead
The with_exclusive_scope examples no longer work in Rails3 because with_exclusive_scope is now a protected method which can and should not be used in a controller. Use the new unscoped method instead:
Article.unscoped
For mor details and examples have a look at: http://github.com/rails/rails/commit/bd1666ad1de88598ed6f04ceffb8488a77be4385.

When using enumerables
When using enumerables and storing them as strings in the database don’t forget to use .to_s or the select helper won’t automatically select your choice when viewing your data after save.
Exemple:
dates = 1900..Date.today.year f.select(:year, dates.collect {|d| [d.to_s,d.to_s]}, {:include_blank => "Select"}, {:class => "some_class"} )

Path Segments
url_options Returns a hash with path segments.
Example:
{:_path_segments=>{:action=>"show", :location=>"los-angeles-ca", :controller=>"city"}, :script_name=>"", :protocol=>"http://", :host=>"localhost:3000"}

Testing Named Scopes
Thanks for the example of testing named_scopes. Being new to Rails, I struggled to find examples that I could understand. Here is another “simple” test for a named_scope
Mine differs slightly from the one above in that I had to remove a set of {} in the :conditions in my test to avoid an “odd number list for Hash” error. I also replace the param-binding “?” with the number I expect to send in as an argument. My test would did know what args[0] was. I got an “undefined local variable” error.
The named scope in my model:
named_scope :up_to_and_including_year, lambda{ |*args| {
:conditions => [“to_char(grad_dt1,‘YYYY’) <= ?”, args[0]] }}
The test:
test "named_scope :up_to_and_including_year" do expected_options = { :conditions => ["to_char(grad_dt1,'YYYY') <= ?", '2010'] } assert_equal expected_options, Sso::CourseTaken.up_to_and_including_year('2010').proxy_options end

Inverse function
String#underscore is inverse for the camelize.
“active_record”.camelize.underscore # => “active_record”

assert_select negative with regex
(also, you can use instance vars)
assert_select "div#event_#{assigns[event].id}", { :count => 0, :html => /something/ }

label DOES translate
Maybe it used to not translate but I know it does as of 2.3.8. It is first lookup on the key:
helpers.label.<object_name>.<method_name>
If that doesn’t return anything it will use the human_attribute_name method on ActiveRecord::Base to translated which uses:
activerecord.attributes.<object>.<attribute>
I generally use both of these keys even when I don’t want to translate but just to have a single place where all my adjusted labels are stored.
If any form will need to use the same adjustment given the same object and attribute then I put in on the activerecord key. If the adjustment is form specific then I put it on the helpers key. Here is an example from real working code:
en: activerecord: attributes: "content/rich_text": name: Page name helpers: label: content_rich_text: testimonial_enabled: Enabled
Note that my AR object is a namespaced object (Content::RichText). In the activerecord key I need to change this to content/rich_text so if can find the correct key and put it in quotes to make it valid YAML. At the helper level on the other hand the namespace simply becomes an _.

:confirm, :popup, and :method override :onclick
upplying any combination of :confirm, :popup, and/or :method options to the link_to method results the :onclick option being overridden.
Example:
link_to "Delete", '#', :confirm=>"Are you sure?", :onclick=>"destroyJsFunction()" # expected output # => <a href="#" onclick="if(confirm('Are you sure?')) {destroyJsFunction()}; return false;">Delete</a> # actual output # => <a href="#" onclick="return confirm('Are you sure?');">Delete</a>
Note that the actual output doesn’t include any mention of the “destroyJsFunction()” passed to the link_to method.
Rails 3 will use unobtrusive JavaScript, and I haven’t tested how that will interact with the :onclick option.

Using strings as association names - beware of HashWithIndifferentAccess
If you merge a normal Hash into a HashWithIndifferentAccess, then the keys will convert to strings…
This will likely bite you if the merge is passed to AR find: as netmaniac said “Beware, that using strings as association names, when giving Hash to :include will render errors”.
Beware that params from your controller are HashWithIndifferentAccess like.

If your add_index is being ignored in your migration, see this
My add_index command was producing no change in my MySQL 5.0 database:
add_index :designations, [ :scope_type, :scope_id, :role_id, :user_id ], :unique => true
By just adding an index name, the problem was solved:
add_index :designations, [ :scope_type, :scope_id, :role_id, :user_id ], :unique => true, :name => 'my_index'
This happens when the autogenerated index name gets too long. For more info see:

To use in testing
If you want to use this in a test, add the following to test_helper.rb:
include ActionDispatch::TestProcess
(If using factory_girl, you can call it in your Factory, like so:
f.photo { fixture_file_upload 'test.png', 'image/png' }

Moved in Rails 3
In Rails 3, this has moved to ActionDispatch::TestProcess
(Which means, if you want to use it in a test, you need to add the following to test_helper.rb:)
include ActionDispatch::TestProcess

When scripts don't end in .js
For example, Google Custom Search’s URL is http://www.google.com/jsapi
It’s an ugly hack, but works:
= javascript_include_tag('http://www.google.com/jsapi').sub('.js', '')

See in_place_editing as the new update
See http://github.com/cementhorses/in_place_editing for the new plugin to use as a substitute.

redirect_to :root
You can redirect to your main page using
redirect_to :root
Make sure to configure to root route first:

to set NULL => NO
use :null => false
change_column :my_table, :my_column, :integer, :default => 0, :null => false

Changing to MySql:BIGINT
I can change a column type from INT to BIGINT with this command:
change_column :my_table, :my_column, :bigint

Routing changes in Rails 3
See ActionDispatch::Routing for routing in Rails 3.