Class: CrudMuffins::Rails::Adapter

Inherits:
Object
  • Object
show all
Defined in:
lib/crud-muffins-rails.rb

Overview

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.

Defined Under Namespace

Classes: Collection

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model) ⇒ Adapter

Returns a new instance of Adapter.



110
111
112
# File 'lib/crud-muffins-rails.rb', line 110

def initialize(model)
  @model = model
end

Class Method Details

.build(params) ⇒ Object

makes a new model record with deserialized params and wraps it in the adapter



98
99
100
# File 'lib/crud-muffins-rails.rb', line 98

def self.build(params)
  new(model_class.new(deserialize(params)))
end

.deserialize(params, _model = nil) ⇒ Object

any logic needed to deserialize the params from the frontend, generally should be overridden



103
104
105
# File 'lib/crud-muffins-rails.rb', line 103

def self.deserialize(params, _model = nil)
  params
end

.find(id, within: model_class) ⇒ Object

general finder method that allows finding the record by ID within a scope, and wrapping it with the adapter



80
81
82
# File 'lib/crud-muffins-rails.rb', line 80

def self.find(id, within: model_class)
  new(within.find(id))
end

.find_or_create_by(where, within: model_class) ⇒ Object

similar to Rails #find_or_create_by



85
86
87
# 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

.model_classObject

the ApplicationRecord or other model class that it is an adapter for

Raises:

  • (NotImplementedError)


75
76
77
# File 'lib/crud-muffins-rails.rb', line 75

def self.model_class
  raise NotImplementedError
end

.where(*args) ⇒ Object



93
94
95
# File 'lib/crud-muffins-rails.rb', line 93

def self.where(*args)
  Collection.new(model_class.where(*args), self)
end

.within(within) ⇒ Object



89
90
91
# File 'lib/crud-muffins-rails.rb', line 89

def self.within(within)
  Collection.new(within, self)
end

Instance Method Details

#as_jsonObject



114
115
116
117
118
119
# File 'lib/crud-muffins-rails.rb', line 114

def as_json(*)
  {
    data: properties,
    type: type,
  }
end

#errorsObject

JSON object of the model errors and their full message summaries



151
152
153
154
155
156
157
158
# 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

#propertiesObject

returns the serialized JSON object that will be passed to the frontend

Raises:

  • (NotImplementedError)


126
127
128
# File 'lib/crud-muffins-rails.rb', line 126

def properties
  raise NotImplementedError
end

#saveObject



134
135
136
# File 'lib/crud-muffins-rails.rb', line 134

def save
  model.save
end

#serialize_props(*keys) ⇒ Object

general helper to create a hash with the specified model attributes where their key names are lowerCamelCased



144
145
146
147
148
# 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

#typeObject



121
122
123
# File 'lib/crud-muffins-rails.rb', line 121

def type
  model.class.to_s
end

#update(attributes) ⇒ Object

updates the model with the deserialized attributes



139
140
141
# File 'lib/crud-muffins-rails.rb', line 139

def update(attributes)
  model.update(deserialize(attributes, model))
end

#valid?Boolean

Returns:

  • (Boolean)


130
131
132
# File 'lib/crud-muffins-rails.rb', line 130

def valid?
  model.valid?
end