同じモジュールの他のクラスの属性を拡張およびオーバーライドするにはどうすればよいですか?
概要
Rails でgraphql を使用しているときに、これを使用して、Product レコードに対して実行する突然変異/更新の引数を定義しています。これまでのところ、引数の定義に使用しているファイルは次のとおりです。
module Types
module Input
class ProductInputType < Types::BaseInputObject
argument :name, String, required: false
argument :description, String, required: false
argument :initial_price, Float, required: false
end
end
end
重要なのは、製品の作成時に必要なすべてを定義したいのですが、モデルを更新するときにすべてが必要になるわけではないということです。そこで、2 つの異なるファイルに 2 つの異なるクラスを作成して、それらを必須にするかどうかを決めたいと思いました。
製品を作成するには、次のすべてが必要です。
module Types
module Input
class CreateProductInputType
argument :name, String, required: true
argument :description, String, required: true
argument :initial_price, Float, required: true
end
end
end
ただし、更新するときは、必須の属性を 1 つだけ必要とし、残りはすべて false にする必要があります。
module Types
module Input
class UpdateProductInputType
argument :name, String, required: true
end
end
end
最初の ProductInputType をすべて false として要求するデフォルトの動作として設定し、その ProductInputType を拡張して必要な引数のみをオーバーライドするだけで、これらの新しいクラス (CreateProductInputType と UpdateProductInputType) を作成できることを期待していました。次のように動作が変更されました。
module Types
module Input
class CreateProductInputType < ProductInputType
argument :name, String, required: true
argument :initial_price, Float, required: true
end
end
end
module Types
module Input
class UpdateProductInputType < ProductInputType
argument :name, String, required: true
end
end
end
しかし、このままではうまくいきません。これらがすべて同じモジュール内にあることを認識しながら、ProductInputType をこれらのクラスに拡張し、引数をオーバーライドするにはどうすればよいでしょうか?
解決策
1 つの方法は、ActiveSupport::Concern を使用して共通の属性を定義し、それらを InputType クラスに含めることです。
このようにして、入力型クラス内に新しい属性を追加したり、共通の属性をオーバーライドしたりすることもできます。
例:
module Types
module Input
module ProductInputAttributes
extend ActiveSupport::Concern
included do
argument :name, String, required: false
argument :description, String, required: false
argument :initial_price, Float, required: false
end
end
end
end
module Types
module Input
class CreateProductInputType
include ProductInputAttributes
argument :name, String, required: true
end
end
end
module Types
module Input
class UpdateProductInputType
include ProductInputAttributes
argument :id, ID, required: true
argument :name, String, required: true
end
end
end