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
@readonlyto false in the record (hack) - Use
:include => :cardinstead 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_sqlis a viable option :readonly => trueis automatically inferred only if:joinswas specified without an explicit:selectnor an explicit (or finder-scope-inherited):readonlyoption (see the implementation ofset_readonly_option!inactive_record/base.rbfor Rails 2.3.4, or the implementation ofto_ainactive_record/relation.rband ofcustom_join_sqlinactive_record/relation/query_methods.rbfor Rails 3.0.0)- however,
:readonly => trueis always automatically inferred inhas_and_belongs_to_manyif the join table has more than the two foreign keys columns and:joinswas specified without an explicit:select(i.e. user-supplied:readonlyvalues 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
:includesif you want to achieve anINNER JOIN(:includesimplies aLEFT OUTER JOIN, which is less selective and less efficient thanINNER JOIN.)