Module: Tama::Model
- Defined in:
- lib/tama/model.rb
Class Method Summary collapse
- .blank?(value) ⇒ Boolean
- .define(*fields, required: [], types: {}, defaults: {}, transforms: {}) ⇒ Object
- .hash(input) ⇒ Object
- .type_name(expected) ⇒ Object
- .valid_type?(value, expected) ⇒ Boolean
- .validate!(values, required:, types:, name:) ⇒ Object
Class Method Details
.blank?(value) ⇒ Boolean
69 70 71 |
# File 'lib/tama/model.rb', line 69 def blank?(value) value.nil? || (value.is_a?(String) && value.empty?) end |
.define(*fields, required: [], types: {}, defaults: {}, transforms: {}) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/tama/model.rb', line 9 def define(*fields, required: [], types: {}, defaults: {}, transforms: {}) Class.new(Data.define(*fields)) do define_singleton_method(:fields) { fields } define_method(:initialize) do |**attributes| unknown = attributes.keys - fields unless unknown.empty? raise Tama::Error::ValidationError.new("Unknown attributes: #{unknown.join(", ")}", errors: {attributes: unknown}) end values = fields.to_h { |field| [field, attributes.fetch(field, defaults.fetch(field, nil))] } Tama::Model.validate!(values, required:, types:, name: self.class.name) super(**values) end define_singleton_method(:parse) do |input| data = Tama::Model.hash(input) values = fields.to_h do |field| value = data.key?(field.to_s) ? data[field.to_s] : data[field] value = transforms.fetch(field).call(value) if !value.nil? && transforms.key?(field) [field, value.nil? ? defaults.fetch(field, nil) : value] end new(**values) rescue Tama::Error::ParseError raise rescue Tama::Error => e raise Tama::Error::ParseError, "Invalid #{name || "model"}: #{e.}" rescue => e raise Tama::Error::ParseError, "Invalid #{name || "model"}: #{e.}" end end end |
.hash(input) ⇒ Object
43 44 45 46 47 48 49 50 |
# File 'lib/tama/model.rb', line 43 def hash(input) input = JSON.parse(input) if input.is_a?(String) raise Tama::Error::ParseError, "Expected a JSON object" unless input.is_a?(Hash) input rescue JSON::ParserError => e raise Tama::Error::ParseError, "Malformed JSON: #{e.}" end |
.type_name(expected) ⇒ Object
77 78 79 |
# File 'lib/tama/model.rb', line 77 def type_name(expected) Array(expected).join(" or ") end |
.valid_type?(value, expected) ⇒ Boolean
73 74 75 |
# File 'lib/tama/model.rb', line 73 def valid_type?(value, expected) Array(expected).any? { |type| value.is_a?(type) } end |
.validate!(values, required:, types:, name:) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/tama/model.rb', line 52 def validate!(values, required:, types:, name:) missing = required.select { |field| blank?(values[field]) } unless missing.empty? raise Tama::Error::ValidationError.new("Missing required fields: #{missing.join(", ")}", errors: {required: missing}) end types.each do |field, expected| value = values[field] next if value.nil? || valid_type?(value, expected) raise Tama::Error::ValidationError.new( "#{field} has an invalid type for #{name || "model"}", errors: {field => "must be #{type_name(expected)}"} ) end end |