class CrudMuffins::Rails::Adapter
ApplicationAdapter is the general structure of a serializer. It returns data through `as_json`.
We tried going through many different serializer libraries (FastJsonApi, ActiveModel Serializers, Roar, Representable, and Grape) and they all didn't do what we want. Basically, we want something that can magically convert snake_case to camelCase for us, to serve as a bridge between frontend and backend data representation when necessary, and to return errors when the model has them.
It turns out it was simpler to implement our own, which is what we've done here as a first pass.
Adapters are intended to wrap an ApplicationRecord, and should be able to delegate basic operations like `update` and `save` to the model, while still keeping it wrapped so it can return serialized data.
Attributes
Public Class Methods
makes a new model record with deserialized params and wraps it in the adapter
# File lib/crud-muffins-rails.rb, line 98 def self.build(params) new(model_class.new(deserialize(params))) end
any logic needed to deserialize the params from the frontend, generally should be overridden
# File lib/crud-muffins-rails.rb, line 103 def self.deserialize(params, _model = nil) params end
general finder method that allows finding the record by ID within a scope, and wrapping it with the adapter
# File lib/crud-muffins-rails.rb, line 80 def self.find(id, within: model_class) new(within.find(id)) end
similar to Rails
find_or_create_by
# File lib/crud-muffins-rails.rb, line 85 def self.find_or_create_by(where, within: model_class) new(within.find_or_create_by(where)) end
the ApplicationRecord or other model class that it is an adapter for
# File lib/crud-muffins-rails.rb, line 75 def self.model_class raise NotImplementedError end
# File lib/crud-muffins-rails.rb, line 110 def initialize(model) @model = model end
# File lib/crud-muffins-rails.rb, line 93 def self.where(*args) Collection.new(model_class.where(*args), self) end
# File lib/crud-muffins-rails.rb, line 89 def self.within(within) Collection.new(within, self) end
Public Instance Methods
# File lib/crud-muffins-rails.rb, line 114 def as_json(*) { data: properties, type: type, } end
JSON object of the model errors and their full message summaries
# File lib/crud-muffins-rails.rb, line 151 def errors { # Summary of all errors errors: model.errors.full_messages, # Errors associated with each attribute modelErrors: model.errors.messages.transform_keys { |key| key.to_s.camelize(:lower) } } end
returns the serialized JSON object that will be passed to the frontend
# File lib/crud-muffins-rails.rb, line 126 def properties raise NotImplementedError end
# File lib/crud-muffins-rails.rb, line 134 def save model.save end
general helper to create a hash with the specified model attributes where their key names are lowerCamelCased
# File lib/crud-muffins-rails.rb, line 144 def serialize_props(*keys) keys.each_with_object({}) do |key, acc| acc[key.to_s.camelize(:lower).to_sym] = self.respond_to?(key) ? self.send(key) : model.send(key) end end
# File lib/crud-muffins-rails.rb, line 121 def type model.class.to_s end
updates the model with the deserialized attributes
# File lib/crud-muffins-rails.rb, line 139 def update(attributes) model.update(deserialize(attributes, model)) end
# File lib/crud-muffins-rails.rb, line 130 def valid? model.valid? end