이 ActiveRecord :: ReadOnlyRecord 오류의 원인은 무엇입니까?
이 다음 이 대답했다 이전에 질문을. 실제로 해당 쿼리에서 조인을 제거 할 수 있음을 발견 했으므로 이제 작동중인 쿼리는
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_id및 hand_id열 이 있습니다 .
Rails API에서 ReadOnlyRecord를 찾았으며 설명을 넘어서는 말은 많지 않습니다.
레일 2.3.3 이하
로부터 액티브 CHANGELOG(v1.12.0 년 10 월 16 일, 2005) :
읽기 전용 레코드를 소개하십시오. object.readonly를 호출하면! 그런 다음 객체를 읽기 전용으로 표시하고 object.save를 호출하면 ReadOnlyRecord를 발생시킵니다. object.readonly? 객체가 읽기 전용인지 여부를보고합니다. 모든 finder 메소드에 : readonly => true를 전달하면 반환 된 레코드가 읽기 전용으로 표시됩니다. : joins 옵션은 이제 : readonly를 의미하므로이 옵션을 사용하면 동일한 레코드를 저장할 수 없습니다. find_by_sql을 사용하여 해결하십시오.
를 사용 find_by_sql하는 것은 실제로 원시 행 / 열 데이터를 반환하므로 대안이 아닙니다 ActiveRecords. 두 가지 옵션이 있습니다.
@readonly레코드에서 인스턴스 변수 를 false로 설정 (해킹):include => :card대신에 사용:join => :card
레일 2.3.4 이상
위의 대부분은 2012 년 9 월 10 일 이후 더 이상 적용되지 않습니다.
- 사용하는
Record.find_by_sql것입니다 가능한 옵션 :readonly => true자동으로 유추되는 경우에만 경우:joins지정 하지 않고 명시 적으로:select도 (상속 범위 파인더 나) 명시 적:readonly옵션은 (의 구현 볼 수set_readonly_option!있는active_record/base.rb레일 2.3.4에 대한, 또는의 구현to_a에서active_record/relation.rb와의custom_join_sql에서active_record/relation/query_methods.rb레일 3.0.0를 들어)- 그러나 조인 테이블에 두 개 이상의 외래 키 열이 있고 명시 적으로 지정되지 않은 경우 (즉, 사용자 제공 값은 무시 됩니다 . 참조
:readonly => true) 항상 자동으로 추론됩니다 .has_and_belongs_to_many:joins:select:readonlyfinding_with_ambiguous_select?active_record/associations/has_and_belongs_to_many_association.rb - 결론적으로, 특별한 취급하지 않는 테이블에 가입하고
has_and_belongs_to_many다음@aaronrustad의 대답은 레일 2.3.4과 3.0.0에서 잘 적용됩니다. - 를 달성하려는 경우 사용 하지 마십시오 (을 의미하며 이는 선택보다 덜 효율적 입니다.)
:includesINNER JOIN:includesLEFT OUTER JOININNER JOIN
또는 Rails 3에서는 읽기 전용 방법을 사용할 수 있습니다 ( "..."을 조건으로 대체).
( Deck.joins(:card) & Card.where('...') ).readonly(false)
최근 Rails 릴리스에서 변경되었을 수 있지만이 문제를 해결하는 적절한 방법은 : readonly => false 를 찾기 옵션 에 추가 하는 것입니다.
select ( '*')는 Rails 3.2에서 이것을 고치는 것 같습니다 :
> Contact.select('*').joins(:slugs).where('slugs.slug' => 'the-slug').first.readonly?
=> false
select ( '*')를 생략하면 읽기 전용 레코드가 생성됩니다.
> Contact.joins(:slugs).where('slugs.slug' => 'the-slug').first.readonly?
=> true
이론적 근거를 이해한다고 말할 수는 없지만 적어도 빠르고 깨끗한 해결 방법입니다.
find_by_sql 대신 파인더에서 : select를 지정하면 모든 것이 행복합니다 ...
start_cards = DeckCard.find :all, :select => 'deck_cards.*', :joins => [:card], :conditions => ["deck_cards.deck_id = ? and cards.start_card = ?", @game.deck.id, true]
비활성화하려면 ...
module DeactivateImplicitReadonly
def custom_join_sql(*args)
result = super
@implicit_readonly = false
result
end
end
ActiveRecord::Relation.send :include, DeactivateImplicitReadonly
참고 URL : https://stackoverflow.com/questions/639171/what-is-causing-this-activerecordreadonlyrecord-error
'Programming' 카테고리의 다른 글
| 파이썬에서 PhantomJS를 사용하는 방법이 있습니까? (0) | 2020.05.07 |
|---|---|
| 아카이브 제출시 Xcode 6 충돌 (0) | 2020.05.07 |
| SQL Server Management Studio에서 열 값을 NULL로 설정하는 방법 (0) | 2020.05.07 |
| PHP에서 경고 메시지 제거 (0) | 2020.05.07 |
| Visual Studio 2015 vshub는 스팸 피들러입니다. (0) | 2020.05.07 |