module Graphiti::Resource::Persistence

Public Instance Methods

add_callback(kind, lifecycle, method, only, &blk) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 65
def add_callback(kind, lifecycle, method, only, &blk)
  config[:callbacks][kind] ||= {}
  config[:callbacks][kind][lifecycle] ||= []
  config[:callbacks][kind][lifecycle] << {callback: (method || blk), only: Array(only)}
end
after_attributes(method = nil, only: [:create, :update], &blk) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 11
def after_attributes(method = nil, only: [:create, :update], &blk)
  add_callback(:attributes, :after, method, only, &blk)
end
after_destroy(method = nil, &blk) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 27
def after_destroy(method = nil, &blk)
  add_callback(:destroy, :after, method, [:destroy], &blk)
end
after_save(method = nil, only: [:create, :update], &blk) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 19
def after_save(method = nil, only: [:create, :update], &blk)
  add_callback(:save, :after, method, only, &blk)
end
around_attributes(method = nil, only: [:create, :update], &blk) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 31
def around_attributes(method = nil, only: [:create, :update], &blk)
  if blk
    raise Errors::AroundCallbackProc.new(self, "around_attributes")
  else
    add_callback(:attributes, :around, method, only, &blk)
  end
end
around_destroy(method = nil, &blk) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 55
def around_destroy(method = nil, &blk)
  if blk
    raise Errors::AroundCallbackProc.new(self, "around_destroy")
  else
    add_callback(:destroy, :around, method, [:destroy], &blk)
  end
end
around_persistence(method = nil, only: [:create, :update], &blk) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 47
def around_persistence(method = nil, only: [:create, :update], &blk)
  if blk
    raise Errors::AroundCallbackProc.new(self, "around_persistence")
  else
    add_callback(:persistence, :around, method, only, &blk)
  end
end
around_save(method = nil, only: [:create, :update], &blk) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 39
def around_save(method = nil, only: [:create, :update], &blk)
  if blk
    raise Errors::AroundCallbackProc.new(self, "around_save")
  else
    add_callback(:save, :around, method, only, &blk)
  end
end
assign_attributes(model_instance, update_params, meta = nil) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 122
def assign_attributes(model_instance, update_params, meta = nil)
  adapter.assign_attributes(model_instance, update_params)
end
before_attributes(method = nil, only: [:create, :update], &blk) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 7
def before_attributes(method = nil, only: [:create, :update], &blk)
  add_callback(:attributes, :before, method, only, &blk)
end
before_destroy(method = nil, &blk) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 23
def before_destroy(method = nil, &blk)
  add_callback(:destroy, :before, method, [:destroy], &blk)
end
before_save(method = nil, only: [:create, :update], &blk) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 15
def before_save(method = nil, only: [:create, :update], &blk)
  add_callback(:save, :before, method, only, &blk)
end
build(model, meta = nil) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 118
def build(model, meta = nil)
  adapter.build(model)
end
create(create_params, meta = nil) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 72
def create(create_params, meta = nil)
  model_instance = nil

  run_callbacks :persistence, :create, create_params, meta do
    run_callbacks :attributes, :create, create_params, meta do |params|
      model_instance = call_with_meta(:build, model, meta)
      call_with_meta(:assign_attributes, model_instance, params, meta)
      model_instance
    end

    run_callbacks :save, :create, model_instance, meta do
      model_instance = call_with_meta(:save, model_instance, meta)
    end

    model_instance
  end
end
delete(model_instance, meta = nil) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 130
def delete(model_instance, meta = nil)
  adapter.destroy(model_instance)
end
destroy(id, meta = nil) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 110
def destroy(id, meta = nil)
  model_instance = self.class._find(id: id).data
  run_callbacks :destroy, :destroy, model_instance, meta do
    call_with_meta(:delete, model_instance, meta)
  end
  model_instance
end
save(model_instance, meta = nil) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 126
def save(model_instance, meta = nil)
  adapter.save(model_instance)
end
update(update_params, meta = nil) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 90
def update(update_params, meta = nil)
  model_instance = nil
  id = update_params[:id]
  update_params = update_params.except(:id)

  run_callbacks :persistence, :update, update_params, meta do
    run_callbacks :attributes, :update, update_params, meta do |params|
      model_instance = self.class._find(id: id).data
      call_with_meta(:assign_attributes, model_instance, params, meta)
      model_instance
    end

    run_callbacks :save, :update, model_instance, meta do
      model_instance = call_with_meta(:save, model_instance, meta)
    end
  end

  model_instance
end

Private Instance Methods

around_callback_proc(callbacks, index, *args, &blk) click to toggle source

The tricky thing here is we need to yield to the next around callback until there are no more callbacks, then we want to call the original block Also keep in mind each callback needs to yield to the next

# File lib/graphiti/resource/persistence.rb, line 183
def around_callback_proc(callbacks, index, *args, &blk)
  method_name = callbacks[index][:callback]

  if callbacks[index + 1]
    proc do
      r = nil
      args = args[0..0] if method(method_name).arity == 1
      send(method_name, *args) do |r2|
        wrapped = around_callback_proc(callbacks, index + 1, r2, &blk)
        r = instance_exec(r2, &wrapped)
      end
      r
    end
  else
    proc do |*args2|
      r = nil
      args2 = args2[0..0] if method(callbacks[index][:callback]).arity == 1
      send(callbacks[index][:callback], *args2) do |r2|
        r = instance_exec(r2, &blk)
      end
      r
    end
  end
end
call_with_meta(callback, *args) click to toggle source

Convenience for calling a method or proc while taking into account ‘meta’ is an optional argument

# File lib/graphiti/resource/persistence.rb, line 158
def call_with_meta(callback, *args)
  if callback.respond_to?(:call)
    instance_exec(*args, &callback)
  else
    arity = method(callback).arity
    args = args[0..0] if arity == 1
    args = args[0..1] if arity == 2
    send(callback, *args)
  end
end
fire_around_callbacks(kind, action, *args) { |*args| ... } click to toggle source
# File lib/graphiti/resource/persistence.rb, line 169
def fire_around_callbacks(kind, action, *args, &blk)
  callbacks = self.class.config[:callbacks][kind].try(:[], :around) || []
  callbacks = callbacks.select { |cb| cb[:only].include?(action) }
  if callbacks.length.zero?
    yield(*args)
  else
    prc = around_callback_proc(callbacks, 0, *args, &blk)
    instance_exec(*args, &prc)
  end
end
fire_callbacks(kind, lifecycle, action, *args) click to toggle source
# File lib/graphiti/resource/persistence.rb, line 145
def fire_callbacks(kind, lifecycle, action, *args)
  if (callbacks = self.class.config[:callbacks][kind])
    callbacks = callbacks[lifecycle] || []
    callbacks.each do |config|
      callback = config[:callback]
      next unless config[:only].include?(action)
      call_with_meta(callback, *args)
    end
  end
end
run_callbacks(kind, action, *args) { |*yieldargs| ... } click to toggle source
# File lib/graphiti/resource/persistence.rb, line 136
def run_callbacks(kind, action, *args)
  fire_around_callbacks(kind, action, *args) do |*yieldargs|
    fire_callbacks(kind, :before, action, *yieldargs)
    result = yield(*yieldargs)
    fire_callbacks(kind, :after, action, result, args.last)
    result
  end
end