Wynika to z poprzedniego pytania, na które udzielono odpowiedzi. Odkryłem, że mogę usunąć złączenie z tego zapytania, więc teraz działa zapytanie
start_cards = DeckCard.find :all, :joins => [:card], :conditions => ["deck_cards.deck_id = ? and cards.start_card = ?", @game.deck.id, true]
To wydaje się działać. Jednak gdy próbuję przenieść te karty DeckCards do innego skojarzenia, pojawia się błąd ActiveRecord :: ReadOnlyRecord.
Oto kod
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
oraz odpowiednie Modele (tableau to karty graczy na stole)
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
Wykonuję podobną akcję zaraz po tym kodzie, dodając DeckCards
do ręki graczy, a ten kod działa dobrze. Zastanawiałem się, czy potrzebowałem belongs_to :tableau
w DeckCard Model, ale działa dobrze w przypadku dodawania do ręki gracza. Mam kolumny tableau_id
i hand_id
w tabeli DeckCard.
Spojrzałem na ReadOnlyRecord w interfejsie API szyn i niewiele mówi poza opisem.
źródło
Lub w Rails 3 możesz użyć metody tylko do odczytu (zamień „...” na twoje warunki):
źródło
readonly
funkcji.Mogło się to zmienić w najnowszej wersji Railsów, ale właściwym sposobem rozwiązania tego problemu jest dodanie : readonly => false do opcji find.
źródło
wydaje się, że select ('*') rozwiązuje to problem w Rails 3.2:
Aby to zweryfikować, pominięcie select („*”) powoduje utworzenie rekordu tylko do odczytu:
Nie mogę powiedzieć, że rozumiem uzasadnienie, ale przynajmniej jest to szybkie i czyste obejście.
źródło
select(quoted_table_name + '.*')
readonly(false)
Zamiast find_by_sql możesz określić: wybierz w wyszukiwarce i wszystko znów będzie szczęśliwe ...
start_cards = DeckCard.find :all, :select => 'deck_cards.*', :joins => [:card], :conditions => ["deck_cards.deck_id = ? and cards.start_card = ?", @game.deck.id, true]
źródło
Aby go wyłączyć ...
źródło