是什么导致了这个 ActiveRecord::ReadOnlyRecord 错误? [英] What is causing this ActiveRecord::ReadOnlyRecord error?

查看:29
本文介绍了是什么导致了这个 ActiveRecord::ReadOnlyRecord 错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这跟this 先前的问题,已回答.我实际上发现我可以从那个查询中删除一个连接,所以现在工作查询是

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]  

这似乎有效.但是,当我尝试将这些 DeckCard 移动到另一个关联中时,出现 ActiveRecord::ReadOnlyRecord 错误.

This appears to work. However, when I try to move these DeckCards into another association, I get the ActiveRecord::ReadOnlyRecord error.

这是代码

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

我在这段代码之后做了一个类似的动作,将 DeckCards 添加到玩家手中,该代码运行良好.我想知道我是否需要在 DeckCard 模型中使用 belongs_to :tableau,但它可以很好地添加到玩家的手上.我在 DeckCard 表中有一个 tableau_idhand_id 列.

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 tableau_id and hand_id columns in the DeckCard table.

我在 rails api 中查找了 ReadOnlyRecord,它没有说太多超出描述的内容.

I looked up ReadOnlyRecord in the rails api, and it doesn't say much beyond the description.

推荐答案

Rails 2.3.3 及更低版本

来自 ActiveRecord CHANGELOG(v1.12.0,2005 年 10 月 16 日):

引入只读记录.如果你调用 object.readonly!那么它会将对象标记为只读并引发ReadOnlyRecord 如果你打电话对象.保存.对象.只读?报告对象是否只读.传递 :readonly => true 到任何finder 方法将标记返回记录为只读.:joins选项现在意味着:只读,所以如果你使用这个选项,保存相同的记录现在将失败. 使用 find_by_sql工作.

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.

使用 find_by_sql 并不是真正的替代方法,因为它返回原始行/列数据,而不是 ActiveRecords.您有两个选择:

Using find_by_sql is not really an alternative as it returns raw row/column data, not ActiveRecords. You have two options:

  1. 在记录中强制实例变量 @readonly 为 false (hack)
  2. 使用 :include =>:card 而不是 :join =>:card
  1. Force the instance variable @readonly to false in the record (hack)
  2. Use :include => :card instead of :join => :card

Rails 2.3.4 及更高版本

以上大部分内容在 2012 年 9 月 10 日之后不再适用:

Most of the above no longer holds true, after September 10 2012:

  • 使用Record.find_by_sql 一个可行的选择
  • :readonly =>true:joins被指定没有显式:select时自动推断也没有显式(或finder-scope-in​​herited):readonly选项(参见active_record/base.rbset_readonly_option!的实现Rails 2.3.4 的代码>,或 active_record/relation.rb 中的 to_aactive_record/relation 中的 custom_join_sql 的实现/query_methods.rb 适用于 Rails 3.0.0)
  • 然而,:readonly =>true 总是在 has_and_belongs_to_many 中自动推断,如果连接表有两个以上的外键列并且 :joins 是在没有明确的 :select 的情况下指定的(即用户提供的 :readonly 值被忽略——参见 active_record/associations/has_and_belongs_to_many_association.rb 中的 finding_with_ambiguous_select?.)
  • 总而言之,除非处理特殊的连接表和 has_and_belongs_to_many,否则 @aaronrustad 的答案在 Rails 2.3.4 和 3.0.0 中都适用.
  • 不要使用 :includes 如果你想实现一个 INNER JOIN(:includes 意味着 :includescode>LEFT OUTER JOIN,它比 INNER JOIN 选择性和效率低.)
  • 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 of set_readonly_option! in active_record/base.rb for Rails 2.3.4, or the implementation of to_a in active_record/relation.rb and of custom_join_sql in active_record/relation/query_methods.rb for Rails 3.0.0)
  • however, :readonly => true is always automatically inferred in has_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 -- see finding_with_ambiguous_select? in active_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 an INNER JOIN (:includes implies a LEFT OUTER JOIN, which is less selective and less efficient than INNER JOIN.)

这篇关于是什么导致了这个 ActiveRecord::ReadOnlyRecord 错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆