DmitryTsepelev / store_model

Work with JSON-backed attributes as ActiveRecord-ish models
MIT License
1.08k stars 87 forks source link

GraphQL input type fails to cast #120

Open OlegSavinov opened 2 years ago

OlegSavinov commented 2 years ago

Hi! Thank you for a really cool gem first of all. The issue raises when the model get Input type from GraphQL mutation and Rails defines it as an instance of a different from Model or JSON type (in my case )

The set up is as follows

create_table "meetings", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
      t.json "settings", default: {}
      ...other fields

Child class

class MeetingSettings
  include StoreModel::Model

  attribute :visitor_access, :boolean
  attribute :host_launch, :boolean
  attribute :users_access, :boolean
  attribute :join_request, :boolean
end

Parent class

class Meeting < ApplicationRecord
  attribute :settings, MeetingSettings.to_type
end

The error, when model creates caused by:

StoreModel::Types::CastError:

 #   failed casting #<Types::Inputs::MeetingSettingsInputType: .... > only String, Hash or MeetingSettings instances are allowed

By the source code I defined that lib/store_model/types/one.rb:35:in `cast_value' won't try to cast it and raises error. I guess the resolving will be useful and will make the StoreModel a perfect solution for GraphQL purposes also!

DmitryTsepelev commented 2 years ago

Hi! Can you call .to_h on the Types::Inputs::MeetingSettingsInputType instance? I guess it will help

OlegSavinov commented 2 years ago

Thats what I did, and it helped. Though I could not catch this param in any callbacks, so it needs to be tracked throughout the project and it not very good

DmitryTsepelev commented 2 years ago

We cannot add any possible class to the case statement inside one.rb 🤔 Looks like we need some way to configure these casts on the app level

DmitryTsepelev commented 2 years ago

...or maybe we could check if object has .to_h and just assume that it's something that could become a Hash