lib/introspective_grape/traversal.rb in introspective_grape-0.5.0 vs lib/introspective_grape/traversal.rb in introspective_grape-0.5.2

- old
+ new

@@ -1,56 +1,56 @@ -module IntrospectiveGrape - module Traversal - # 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. - - 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) || return - - 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 - - def verify_records_found(leaves, routes) - return if (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 - - 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 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 - - def verify_record_found(routes, params, record) - return unless 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 -end +module IntrospectiveGrape + module Traversal + # 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. + + 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) || return + + 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 + + def verify_records_found(leaves, routes) + return if (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 + + 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 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 + + def verify_record_found(routes, params, record) + return unless 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 +end