Module: OpenStax::Api::Roar

Included in:
V1::ApiController
Defined in:
lib/openstax/api/roar.rb

Instance Method Summary collapse

Instance Method Details

#render_api_errors(errors, status = :unprocessable_entity) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/openstax/api/roar.rb', line 95

def render_api_errors(errors, status = :unprocessable_entity)
  hash = { status: Rack::Utils.status_code(status) }
  case errors
  when ActiveModel::Errors, Lev::BetterActiveModelErrors
    hash[:errors] = []
    errors.each do |attribute, message|
      hash[:errors] << {
        code: "#{attribute.to_s}_#{message.to_s.gsub(/[\s-]/, '_').gsub(/[^\w]/, '')}",
        message: errors.full_message(attribute, message)
      }
    end
  when Lev::Errors
    hash[:errors] = errors.collect do |error|
      {code: error.code, message: error.message, data: error.data}
    end
  else
    hash[:errors] = [errors].flatten.collect do |error|
      {code: error.to_s}
    end
  end
  render json: hash, status: status
end

#standard_create(model, represent_with = nil, options = {}) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/openstax/api/roar.rb', line 24

def standard_create(model, represent_with=nil, options={})
  model.class.transaction do
    consume!(model, represent_with: represent_with)
    yield model if block_given?
    OSU::AccessPolicy.require_action_allowed!(:create, current_api_user, model)

    if model.save
      respond_with model, represent_with: represent_with,
                          status: :created, location: options[:location]
    else
      render_api_errors(model.errors)
    end
  end
end

#standard_destroy(model) ⇒ Object



63
64
65
66
67
68
69
70
71
# File 'lib/openstax/api/roar.rb', line 63

def standard_destroy(model)
  OSU::AccessPolicy.require_action_allowed!(:destroy, current_api_user, model)

  if model.destroy
    head :no_content
  else
    render_api_errors(model.errors)
  end
end

#standard_index(relation, represent_with) ⇒ Object



73
74
75
76
77
78
79
80
81
# File 'lib/openstax/api/roar.rb', line 73

def standard_index(relation, represent_with)
  model_klass = relation.base_class
  OSU::AccessPolicy.require_action_allowed!(:index, current_api_user, model_klass)
  relation.each do |item|
    # Must be able to read each record
    OSU::AccessPolicy.require_action_allowed!(:read, current_api_user, item)
  end
  respond_with(Lev::Outputs.new(items: relation), represent_with: represent_with)
end

#standard_nested_create(model, container_association, container, represent_with = nil) ⇒ Object



87
88
89
90
91
92
93
# File 'lib/openstax/api/roar.rb', line 87

def standard_nested_create(model, container_association, container, represent_with=nil)
  # Must be able to update the container
  OSU::AccessPolicy.require_action_allowed!(:update, current_api_user, container)
  model.send("#{container_association.to_s}=", container)

  standard_create(model, represent_with)
end

#standard_read(model, represent_with = nil, use_timestamp_for_cache = false) ⇒ Object



39
40
41
42
43
# File 'lib/openstax/api/roar.rb', line 39

def standard_read(model, represent_with=nil, use_timestamp_for_cache=false)
  OSU::AccessPolicy.require_action_allowed!(:read, current_api_user, model)
  respond_with model, represent_with: represent_with \
    if !use_timestamp_for_cache || stale?(model)
end

#standard_search(model, routine, represent_with, options = {}) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/openstax/api/roar.rb', line 12

def standard_search(model, routine, represent_with, options={})
  user = current_api_user
  OSU::AccessPolicy.require_action_allowed!(:search, user, model)
  result = routine.call(params, options)
  return render_api_errors(result.errors) if result.errors.any?
  outputs = result.outputs
  outputs[:items].each do |item|
    OSU::AccessPolicy.require_action_allowed!(:read, user, item)
  end
  respond_with outputs, represent_with: represent_with
end

#standard_sort(*args) ⇒ Object

Raises:

  • (NotYetImplemented)


83
84
85
# File 'lib/openstax/api/roar.rb', line 83

def standard_sort(*args)
  raise NotYetImplemented
end

#standard_update(model, represent_with = nil) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/openstax/api/roar.rb', line 45

def standard_update(model, represent_with=nil)
  # Must be able to update the record before and after the update itself
  OSU::AccessPolicy.require_action_allowed!(:update, current_api_user, model)

  model.with_lock do
    consume!(model, represent_with: represent_with)
    yield model if block_given?
    OSU::AccessPolicy.require_action_allowed!(:update, current_api_user, model)
  
    if model.save
      # http://stackoverflow.com/a/27413178
      respond_with model, represent_with: represent_with, responder: ResponderWithPutContent
    else
      render_api_errors(model.errors)
    end
  end
end