[ruby-on-rails] What is causing this ActiveRecord::ReadOnlyRecord error?
Or in Rails 3 you can use the readonly method (replace "..." with your conditions):
( Deck.joins(:card) & Card.where('...') ).readonly(false)
This follows this prior question, which was answered. I actually discovered I could remove a join from that query, so now the working query is
start_cards = DeckCard.find :all, :joins => [:card], :conditions => ["deck_cards.deck_id = ? and cards.start_card = ?", @game.deck.id, true]
This appears to work. However, when I try to move these DeckCards into another association, I get the ActiveRecord::ReadOnlyRecord error.
Here's the code
for player in @game.players player.tableau = Tableau.new start_card = start_cards.pop start_card.draw_pile = false player.tableau.deck_cards << start_card # the error occurs on this line end
and the relevant Models (tableau are the players cards on the table)
class Player < ActiveRecord::Base belongs_to :game belongs_to :user has_one :hand has_one :tableau end class Tableau < ActiveRecord::Base belongs_to :player has_many :deck_cards end class DeckCard < ActiveRecord::Base belongs_to :card belongs_to :deck end
I am doing a similar action just after this code, adding
DeckCards to the players hand, and that code is working fine. I wondered if I needed
belongs_to :tableau in the DeckCard Model, but it works fine for the adding to player's hand. I do have a
hand_id columns in the DeckCard table.
I looked up ReadOnlyRecord in the rails api, and it doesn't say much beyond the description.
select('*') seems to fix this in Rails 3.2:
> Contact.select('*').joins(:slugs).where('slugs.slug' => 'the-slug').first.readonly? => false
Just to verify, omitting select('*') does produce a readonly record:
> Contact.joins(:slugs).where('slugs.slug' => 'the-slug').first.readonly? => true
Can't say I understand the rationale but at least it's a quick and clean workaround.
To deactivate it...
module DeactivateImplicitReadonly def custom_join_sql(*args) result = super @implicit_readonly = false result end end ActiveRecord::Relation.send :include, DeactivateImplicitReadonly