What is causing this ActiveRecord::ReadOnlyRecord error?
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
.)
What is causing this ActiveRecord::ReadOnlyRecord error?
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
.)
Ruby on Rails: How do I get rid of the ActiveRecord:ReadOnlyRecord error?
If you loaded link_pages via an ARel :join query, you can probably get rid of the error by changing :join to :include.
A similar question with a more detailed answer was answered here.
How can this code throw a ActiveRecord::ReadOnlyRecord exception?
This is probably due to joining in other child values through your find_by_code() helper.
When ActiveRecord uses joins to lookup an object returning additional values, it marks the record read-only.
There's a thorough description of this on this question here:
What is causing this ActiveRecord::ReadOnlyRecord error?
If this is the case, you can probably fix the issue by turning a your :joins into a proper :include that populates the ActiveRecord instances without marking them read-only.
ActiveRecord::ReadOnlyRecord: Diff is marked as readonly on destroy_all
With includes
, Rails will determine whether to use multiple queries (using preload
) or a single left outer join query (using eager_load
). In your case, because your where clause is on the association, Rails will use eager_load
and therefore a LEFT OUTER JOIN. Also note that associations loaded via a join are marked as readonly
and is the cause of the error you're receiving. The solution is to switch includes
to left_joins
and set readonly(false)
prior to calling destroy_all
.
Snippet.left_joins(:diffs).readonly(false).where(diffs: { body: "<div class=\"diff\"></div>"}).destroy_all
NOTE
I originally thought you could do
Snippet.includes(:diffs).readonly(false).where(diffs: { body: "<div class=\"diff\"></div>"}).destroy_all
but this doesn't work for some reason (and don't have enough time to investigate atm). In any case, since using includes
would result in a LEFT OUTER JOIN anyways, you can use the above solution to get the desired outcome.
Rails 3 scoped finds giving ActiveRecord::ReadOnlyRecord
It turns out it was related to using scopes to impersonate active record associations. I was able to fix it by adding .readonly(false)
to my scopes.
Why does this activerecord find query throw an error?
Error: Couldn't find all Movies with 'id': (all, {:order=>"title"})
@movies = Movie.find(:all, :order => (params[:sort]))
That's because the above query only works in Rails 2.x and older. In the later versions of Rails that query won't work!
Checked here, and the first snippet seems it should valid:
https://apidock.com/rails/ActiveRecord/Base/find/class
You are looking into older version of Rails(2.3.8). You can find the reference to newer versions here
Related Topics
Getting Fields_For and Accepts_Nested_Attributes_For to Work With a Belongs_To Relationship
How to Read a User Uploaded File, Without Saving It to the Database
How to Run Rake Tasks Within a Ruby Script
No Such File to Load - Readline
Nokogiri, Open-Uri, and Unicode Characters
How to Get Request Referer Path
How to Convert a String to a Constant in Ruby
Double Pipe Symbols in Ruby Variable Assignment
How to Get a Date from Date_Select or Select_Date in Rails
Ruby - Difference Between Array#≪≪ and Array#Push
Ruby Method Array#≪≪ Not Updating the Array in Hash
Need to Split Arrays to Sub Arrays of Specified Size in Ruby
How to Capture Stdout to a String
Can Ruby Print Out Time Difference (Duration) Readily