小编典典

是什么导致了这个 ActiveRecord::ReadOnlyRecord 错误?

all

这遵循了前面的问题,该问题已得到回答。我实际上发现我可以从该查询中删除一个连接,所以现在工作查询是

start_cards = DeckCard.find :all, :joins => [:card], :conditions => ["deck_cards.deck_id = ? and cards.start_card = ?", @game.deck.id, true]

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

这是代码

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

和相关的模型(画面是桌上的玩家牌)

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到玩家手中,并且该代码运行良好。我想知道我是否需要belongs_to :tableauDeckCard 模型,但它可以很好地添加到玩家的手牌中。我在 DeckCard
表中有一个tableau_idhand_id列。

我在rails api中查找了ReadOnlyRecord,除了描述之外并没有说太多。


阅读 65

收藏
2022-06-28

共1个答案

小编典典

Rails 2.3.3 及更低版本

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

引入只读记录。如果你调用 object.readonly!然后它会将对象标记为只读并在调用 object.save 时引发
ReadOnlyRecord。object.readonly? 报告对象是否是只读的。将 :readonly => true 传递给任何 finder
方法会将返回的记录标记为只读。 :joins 选项现在意味着 :readonly,因此如果您使用此选项,现在保存相同的记录将失败。 使用
find_by_sql 来解决。

Usingfind_by_sql并不是真正的替代方案,因为它返回原始行/列数据,而不是ActiveRecords. 你有两个选择:

  1. 强制实例变量@readonly在记录中为假(hack)
  2. 使用:include => :card代替:join => :card

Rails 2.3.4 及更高版本

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

  • 使用Record.find_by_sql 一个可行的选择
  • :readonly => true只有在 没有* 显式 显式(或finder-scope-in​​herited)选项指定时 才会 自动推断(参见Rails 2.3.4的in实现,或Rails 3.0.0的in和in的实现):joins :select ***:readonly``set_readonly_option!``active_record/base.rb``to_a``active_record/relation.rb``custom_join_sql``active_record/relation/query_methods.rb
  • 但是,如果连接表有两个以上的外键列并且没有明确指定(即忽略用户提供的值 - 参见.) ,:readonly => true则总是自动推断in 。has_and_belongs_to_many``:joins``:select``:readonly``finding_with_ambiguous_select?``active_record/associations/has_and_belongs_to_many_association.rb
  • 总之,除非处理特殊的连接表和has_and_belongs_to_many,否则@aaronrustad的答案在 Rails 2.3.4 和 3.0.0 中适用。
  • 如果:includes您想实现INNER JOIN(:includes意味着 a LEFT OUTER JOIN,它的选择性和效率低于INNER JOIN.) ,请不要使用
2022-06-28