Rails 2.3.3 and lower
From the ActiveRecord CHANGELOG
(v1.12.0, October 16th, 2005):
Introduce read-only records. If you call object.readonly! then it will
mark the object as read-only and raise
ReadOnlyRecord if you call
object.save. object.readonly? reports
whether the object is read-only.
Passing :readonly => true to any
finder method will mark returned
records as read-only. The :joins
option now implies :readonly, so if
you use this option, saving the same
record will now fail. Use find_by_sql
to work around.
Using find_by_sql
is not really an alternative as it returns raw row/column data, not ActiveRecords
. You have two options:
- Force the instance variable
@readonly
to false in the record (hack) - Use
:include => :card
instead of:join => :card
Rails 2.3.4 and above
Most of the above no longer holds true, after September 10 2012:
- using
Record.find_by_sql
is a viable option :readonly => true
is automatically inferred only if:joins
was specified without an explicit:select
nor an explicit (or finder-scope-inherited):readonly
option (see the implementation ofset_readonly_option!
inactive_record/base.rb
for Rails 2.3.4, or the implementation ofto_a
inactive_record/relation.rb
and ofcustom_join_sql
inactive_record/relation/query_methods.rb
for Rails 3.0.0)- however,
:readonly => true
is always automatically inferred inhas_and_belongs_to_many
if the join table has more than the two foreign keys columns and:joins
was specified without an explicit:select
(i.e. user-supplied:readonly
values are ignored — seefinding_with_ambiguous_select?
inactive_record/associations/has_and_belongs_to_many_association.rb
.) - in conclusion, unless dealing with a special join table and
has_and_belongs_to_many
, then@aaronrustad
‘s answer applies just fine in Rails 2.3.4 and 3.0.0. - do not use
:includes
if you want to achieve anINNER JOIN
(:includes
implies aLEFT OUTER JOIN
, which is less selective and less efficient thanINNER JOIN
.)