Я новичок как в rails, так и в graphql. Я пытаюсь реализовать какой-то простой API, содержащий 3 типа объектов, игр, персонажей и цитаты. Каждая игра может иметь несколько персонажей. Вот типы и мутации, которые я написал. (Проблема связана с играми и персонажами, поэтому я их вставлю.)
GameType:
module Types
class GameType < Types::BaseObject
field :id, ID, null: false
field :name, String, null: false
field :characters, [Types::CharacterType], null: true do
#pagination, and cap number of characters retrieved to 20
argument :first, Integer, default_value: 20, required: false, prepare: ->(limit, ctx) {[limit, 20].min}
argument :offset, Integer, default_value: 0, required: false
end
field :quotes, [Types::QuoteType], null: true do
#pagination, and cap number of quotes retrieved to 20
argument :first, Integer, default_value: 20, required: false, prepare: ->(limit, ctx) {[limit, 20].min}
argument :offset, Integer, default_value: 0, required: false
end
field :character_count, Integer, null: true
field :quote_count, Integer, null: true
def characters(first:, offset:)
object.characters.first(first).offset(offset)
end
def quotes(first:, offset:)
object.quotes.first(first).offset(offset)
end
def character_count
object.characters.count
end
def quote_count
object.quotes.count
end
end
end
CharacterType:
module Types
class CharacterType < Types::BaseObject
field :id, ID, null: false
field :name, String, null: false
field :game, Types::GameType, null: false
field :quotes, [Types::QuoteType], null: true do
#pagination, and cap number of quotes retrieved to 20
argument :first, Integer, default_value: 20, required: false, prepare: ->(first, ctx) {[first, 20].min}
argument :offset, Integer, default_value: 0, required: false
end
field :quote_count, Integer, null: true
def quotes(first:, offset:)
object.quotes.first(first).offset(offset)
end
def quote_count
object.quotes.size
end
end
end
Мутация CreateGame:
class Mutations::CreateGame < Mutations::BaseMutation
argument :name, String, required: true
field :game, Types::GameType, null: false
field :errors, [String], null: false
def resolve(name:)
game = Game.new(name: name)
if game.save
# Successful creation, return the created object with no errors
{
game: game,
errors: [],
}
else
# Failed save, return the errors to the client
{
game: nil,
errors: game.errors.full_messages
}
end
end
end
Мутация CreateCharacter:
class Mutations::CreateCharacter < Mutations::BaseMutation
argument :name, String, required: true
argument :gameId, Integer, required: true
field :character, Types::CharacterType, null: false
field :errors, [String], null: false
def resolve(name:, gameId:)
game = Game.find(gameId)
if game.nil?
return {
character: nil,
errors: game.errors.full_messages,
}
end
character = Character.new(name: name, game: game)
game = game.update(characters: game.characters + [character])
^^^^^^ error on this line
if character.save
# Successful creation, return the created object with no errors
{
character: character,
errors: [],
}
else
# Failed save, return the errors to the client
{
character: nil,
errors: character.errors.full_messages + game.errors.full_messages
}
end
end
end
app / models / game.rb:
class Game < ApplicationRecord
end
app / models / character.rb:
class Character < ApplicationRecord
belongs_to :game
end
db / schema.rb:
ActiveRecord::Schema.define(version: 2020_04_30_071223) do
create_table "characters", force: :cascade do |t|
t.integer "game_id", null: false
t.string "name"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["game_id"], name: "index_characters_on_game_id"
end
create_table "games", force: :cascade do |t|
t.string "name"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "quotes", force: :cascade do |t|
t.integer "game_id", null: false
t.integer "character_id", null: false
t.string "text"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["character_id"], name: "index_quotes_on_character_id"
t.index ["game_id"], name: "index_quotes_on_game_id"
end
add_foreign_key "characters", "games"
add_foreign_key "quotes", "characters"
add_foreign_key "quotes", "games"
end
CreateGame работает правильно, но CreateCharacter выдает мне эту ошибку (строка помечена в CreateCharacter):
undefined method `characters' for #<Game:0x00007fdf4c207c30>
/var/lib/gems/2.5.0/gems/activemodel-6.0.2.2/lib/active_model/attribute_methods.rb:431:in `method_missing'
/home/krypt/myStuff/projects/gameq/gameq_api/app/graphql/mutations/create_character.rb:19:in `resolve'
Как мне почини это? Спасибо!