이 활성 레코드의 원인: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 :tableau
DeckCard 모델에서는 사용할 수 있지만 플레이어의 손에 추가하는 데는 문제가 없습니다.나는 있습니다.tableau_id
그리고.hand_id
열을 표시할 수 있습니다.
레일즈 API에서 ReadOnly Record를 찾아봤는데 설명 이상의 내용은 없습니다.
레일 2.3.3 이하
활성 레코드에서:
읽기 전용 레코드를 소개합니다.object.readonly!를 호출하면 개체가 읽기 전용으로 표시되고 object.save.object.readonly?를 호출하면 ReadOnlyRecord가 표시됩니다.개체가 읽기 전용인지 여부를 보고합니다.finder 메서드에 :read only => true를 전달하면 반환된 레코드가 읽기 전용으로 표시됩니다.:joins 옵션은 이제 :readonly를 의미하므로 이 옵션을 사용하면 동일한 레코드 저장이 실패합니다.find_by_sql을 사용하여 해결합니다.
사용.find_by_sql
Raw 행/컬럼 데이터를 반환하기 때문에 실제 대안은 아닙니다.ActiveRecords
두 가지 옵션이 있습니다.
- 인스턴스 변수 강제 적용
@readonly
기록에 거짓이 있음 (계속) - 사용하다
: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
(즉, 사용자 제공):readonly
값이 무시됩니다. 참조finding_with_ambiguous_select?
에active_record/associations/has_and_belongs_to_many_association.rb
.) - 결론적으로, 특별한 공동 테이블을 다루지 않는 한.
has_and_belongs_to_many
,그리고나서@aaronrustad
은 Rails .4.0에 Rails 2.3.4 및 3.0.0 잘 적 용 됩 니 다 - 사용하지 않음
:includes
만약 당신이 성취하기를 원한다면.INNER JOIN
(:includes
을 의미합니다.LEFT OUTER JOIN
보다 덜 선택적이고 덜 효율적인.INNER JOIN
.)
또는 레일 3에서 읽기 전용 방법을 사용할 수 있습니다("..."을 조건으로 대체).
( Deck.joins(:card) & Card.where('...') ).readonly(false)
이것은 최근 Rails 릴리스에서 변경되었을 수 있지만 이 문제를 해결하는 적절한 방법은 찾기 옵션에 :readonly => false를 추가하는 것입니다.
select('*')는 레일 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
'it-source' 카테고리의 다른 글
Azure 테이블 저장소 행 키 제한된 문자 패턴? (0) | 2023.06.10 |
---|---|
장고: 개발 및 생산 설정을 어떻게 관리합니까? (0) | 2023.06.06 |
Firebase 동적 링크 지원 사용자 지정 매개 변수? (0) | 2023.06.06 |
경고:-분리된 뷰 컨트롤러에는 뷰 컨트롤러를 표시하지 마십시오. (0) | 2023.06.06 |
py.test 내부 사용 중지 경고를 억제하는 방법 (0) | 2023.06.06 |