Module: JSONAPI::Routing

Defined in:
lib/json_api/routing.rb

Instance Method Summary collapse

Instance Method Details

#jsonapi_resources(resource, controller: nil, defaults: {}, sti: false, **options, &block) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/json_api/routing.rb', line 5

def jsonapi_resources(resource, controller: nil, defaults: {}, sti: false, **options, &block)
  resource_name = resource.to_s

  # Smart Controller Detection:
  # If no controller is specified, try to find one in the current scope.
  # If we find "Trust::VendorsController", use it (by passing nil to 'resources').
  # If NOT found, default to the generic "json_api/resources".
  if controller.nil?
    scoped_module = @scope[:module]
    potential_controller_name = if scoped_module
                                  "#{scoped_module.to_s.camelize}::#{resource_name.pluralize.camelize}Controller"
                                else
                                  "#{resource_name.pluralize.camelize}Controller"
                                end

    begin
      # Check if the controller exists constant
      potential_controller_name.constantize
      # It exists! Leave controller as nil so Rails uses standard routing conventions
    rescue NameError
      # It doesn't exist, fallback to generic controller
      controller = "json_api/resources"
    end
  end

  # Validate that resource class exists at boot time
  JSONAPI::ResourceLoader.find(resource_name)

  defaults = defaults.merge(format: :jsonapi, resource_type: resource_name)

  options[:only] = :index if sti

  resources(resource, controller:, defaults:, **options) do
    member do
      get "relationships/:relationship_name", to: "json_api/relationships#show", as: :relationship
      patch "relationships/:relationship_name", to: "json_api/relationships#update"
      delete "relationships/:relationship_name", to: "json_api/relationships#destroy"
    end

    instance_eval(&block) if block
  end

  return unless sti

  if sti.is_a?(Array)
    sti.each do |sub_resource_name|
      jsonapi_resources(sub_resource_name, defaults:)
    end
  else
    begin
      resource_class = JSONAPI::ResourceLoader.find(resource_name)
      model_class = resource_class.model_class

      if model_class.respond_to?(:descendants)
        model_class.descendants.each do |subclass|
          sub_resource_name = subclass.name.underscore.pluralize.to_sym
          next if sub_resource_name == resource.to_sym

          jsonapi_resources(sub_resource_name, defaults:)
        end
      end
    rescue NameError, JSONAPI::ResourceLoader::MissingResourceClass
      # Silently skip if model/resource not found
    end
  end
end