Module: IntrospectiveGrape::Traversal
- Included in:
- API
- Defined in:
- lib/introspective_grape/traversal.rb
Instance Method Summary collapse
- #find_leaf(routes, record, params) ⇒ Object
-
#find_leaves(routes, record, params) ⇒ Object
For deeply nested endpoints we want to present the record being affected, these methods traverse down from the parent instance to the child model associations of the deeply nested route.
- #verify_record_found(routes, params, record) ⇒ Object
- #verify_records_found(leaves, routes) ⇒ Object
Instance Method Details
#find_leaf(routes, record, params) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/introspective_grape/traversal.rb', line 32 def find_leaf(routes, record, params) return record unless routes.size > 1 # For deeply nested routes we need to search from the root of the API to the leaf # of its nested associations in order to guarantee the validity of the relationship, # the authorization on the parent model, and the sanity of passed parameters. routes[1..-1].each_with_index do |r| if record && params[r.key] ref = r.reflection record = record.send(ref.name).where( id: params[r.key] ).first if ref end end verify_record_found(routes, params, record) record end |
#find_leaves(routes, record, params) ⇒ Object
For deeply nested endpoints we want to present the record being affected, these methods traverse down from the parent instance to the child model associations of the deeply nested route.
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/introspective_grape/traversal.rb', line 6 def find_leaves(routes, record, params) # Traverse down our route and find the leaf's siblings from its parent, e.g. # project/#/teams/#/team_users ~> project.find.teams.find.team_users # (the traversal of the intermediate nodes occurs in find_leaf()) return record if routes.size < 2 # the leaf is the root record = find_leaf(routes, record, params) if record assoc = routes.last if assoc.many? leaves = record.send( assoc.reflection.name ).includes( default_includes(assoc.model) ) verify_records_found(leaves, routes) leaves else # has_one associations don't return a CollectionProxy and so don't support # eager loading. record.send( assoc.reflection.name ) end end end |
#verify_record_found(routes, params, record) ⇒ Object
48 49 50 51 52 |
# File 'lib/introspective_grape/traversal.rb', line 48 def verify_record_found(routes, params, record) if params[routes.last.key] && record.class != routes.last.model raise ActiveRecord::RecordNotFound.new("No #{routes.last.model.name} with ID '#{params[routes.last.key]}'") end end |
#verify_records_found(leaves, routes) ⇒ Object
26 27 28 29 30 |
# File 'lib/introspective_grape/traversal.rb', line 26 def verify_records_found(leaves, routes) unless (leaves.map(&:class) - [routes.last.model]).empty? raise ActiveRecord::RecordNotFound.new("Records contain the wrong models, they should all be #{routes.last.model.name}, found #{records.map(&:class).map(&:name).join(',')}") end end |