class Roaster::Adapters::ActiveRecord

Public Class Methods

model_class_from_resource_name(resource_name) click to toggle source
# File lib/roaster/adapters/active_record.rb, line 8
def self.model_class_from_resource_name(resource_name)
  "#{resource_name.to_s.singularize}".classify.constantize
end

Public Instance Methods

_change_relationship(query, rel_name, rel_ids, replace: false) click to toggle source

TODO: Please refactor me, i’m ugly

# File lib/roaster/adapters/active_record.rb, line 24
def _change_relationship(query, rel_name, rel_ids, replace: false)
  model = model_for(query.target.resource_name)
  object = model.find(query.target.resource_ids.first)
  rel_model = rel_name.to_s.classify.constantize
  rel_meta = model.reflect_on_association(rel_name)
  rel_object = rel_model.find(rel_ids)
  case rel_meta.macro
  when :has_many
    object.send(rel_name).clear if replace === true
    object.send(rel_name).push(rel_object)
  when :belongs_to
    object.send("#{rel_name}=", rel_object)
  else
    raise "#{rel_meta.macro} relationship not implemented"
  end
  self.save(object)
end
create_relationship(query, document) click to toggle source

TODO:

Document key isn't always rel_name, it's rel_name's resource type
  ( not accessible here right now :-( )
# File lib/roaster/adapters/active_record.rb, line 45
def create_relationship(query, document)
  rel_name = query.target.relationship_name
  rel_ids = document[rel_name.to_s.pluralize]
  _change_relationship(query, rel_name, rel_ids)
end
delete(query) click to toggle source
# File lib/roaster/adapters/active_record.rb, line 78
def delete(query)
  q = scope_for(query.target)
  q.destroy_all
  q
end
find(query, model_class: nil) click to toggle source
# File lib/roaster/adapters/active_record.rb, line 57
def find(query, model_class: nil)
  raise 'No ID provided' if query.target.resource_ids.empty?
  scope_for(query.target, model_class).first
end
new(query, model_class: nil) click to toggle source
# File lib/roaster/adapters/active_record.rb, line 12
def new(query, model_class: nil)
  model = model_for(model_class || query.target.resource_name)
  model.new
end
read(query, model_class: nil) click to toggle source
# File lib/roaster/adapters/active_record.rb, line 62
def read(query, model_class: nil)
  q = scope_for(query.target, model_class)
  query.includes.each do |i|
    q = q.include(i)
  end
  query.filters.each_pair do |k, v|
    q = q.where(k => v)
  end
  query.sorting.each do |resource_name, criteria|
    criteria.each do |field, direction|
      q = q.order(model_for(resource_name).arel_table[field].send(direction))
    end
  end
  q
end
save(model) click to toggle source

TODO: HAX, rethink data path for POST/PUT requests from the start TODO: save! not good if we want to delay adapter request execution

# File lib/roaster/adapters/active_record.rb, line 19
def save(model)
  model.save!
end
update_relationship(query, document) click to toggle source
# File lib/roaster/adapters/active_record.rb, line 51
def update_relationship(query, document)
  document.each do |rel_name, rel_ids|
    _change_relationship(query, rel_name.to_sym, rel_ids, replace: true)
  end
end

Private Instance Methods

model_for(model_class_or_name) click to toggle source
# File lib/roaster/adapters/active_record.rb, line 89
def model_for(model_class_or_name)
  if model_class_or_name.kind_of?(::ActiveRecord::Base)
    model_class_or_name
  else
    self.class.model_class_from_resource_name(model_class_or_name)
  end
end
resource_for(resource_name, id = nil) click to toggle source
# File lib/roaster/adapters/active_record.rb, line 86
def resource_for(resource_name, id = nil)
end
scope_for(target, model_class_or_name = nil) click to toggle source

TODO: Handle ALL, none should be the default: maybe not ?

Move resource stuff into resource_for
# File lib/roaster/adapters/active_record.rb, line 99
def scope_for(target, model_class_or_name = nil)
  model_class = model_for(model_class_or_name || target.resource_name)
  scope = model_class.all
  unless target.resource_ids.empty?
    scope = scope.where(id: target.resource_ids)
  end
  if target.relationship_name
    raise "Cannot apply relationship #{target.relationship_name} to nil object" if scope.count == 0
    raise "Cannot apply relationship #{target.relationship_name} to more than one object" if scope.count > 1
    scope = scope.first.send(target.relationship_name)
  end
  scope
end