Class: Jets::Router::Route::Node

Inherits:
Object
  • Object
show all
Defined in:
lib/jets/router/route/node.rb

Overview

The Node class groups logic that requires both of route and scope info. It does not really belong in either the Route or Scope class and requires both to do its job. So it gets its own class. This seems to help keep the Route and Scope classes simpler.

An instance of this class is made available with each iteration of loop that processes the DSL scopes.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(route, scope) ⇒ Node

Returns a new instance of Node.



11
12
13
14
15
16
# File 'lib/jets/router/route/node.rb', line 11

def initialize(route, scope)
  @route, @scope = route, scope # scope is current scope of iteration
  @info = route.info
  @options = route.options
  @leaf_scope = @route.scope # the route scope is the leaf scope
end

Instance Attribute Details

#leaf_scopeObject (readonly)

Returns the value of attribute leaf_scope.



10
11
12
# File 'lib/jets/router/route/node.rb', line 10

def leaf_scope
  @leaf_scope
end

#routeObject (readonly)

Returns the value of attribute route.



10
11
12
# File 'lib/jets/router/route/node.rb', line 10

def route
  @route
end

#scopeObject (readonly)

Returns the value of attribute scope.



10
11
12
# File 'lib/jets/router/route/node.rb', line 10

def scope
  @scope
end

Instance Method Details

#add_path_segment?Boolean

Accounts for shallow scope. Example:

resources :posts, shallow: true do
  resources :comments do
    resources :likes
  end
end

add_path_segment? = add_path_segment_considering_shallow?

Returns:

  • (Boolean)


41
42
43
44
45
46
47
48
49
# File 'lib/jets/router/route/node.rb', line 41

def add_path_segment?
  if param_action? && shallow_param_action?
    leaf? # only add path segments for leaf
  elsif paramless_action? && shallow_paramless_action?
    leaf? || leaf_scope.real_parent?(scope)
  else
    true # default is to always path preceding path segments
  end
end

#append_as?Boolean

Returns:

  • (Boolean)


26
27
28
29
# File 'lib/jets/router/route/node.rb', line 26

def append_as?
  has_path? && add_path_segment? ||
  scope.from.nil? && scope.as
end

#append_param?Boolean

Returns:

  • (Boolean)


22
23
24
# File 'lib/jets/router/route/node.rb', line 22

def append_param?
  has_param? && add_path_segment?
end

#append_path?Boolean

Returns:

  • (Boolean)


18
19
20
# File 'lib/jets/router/route/node.rb', line 18

def append_path?
  has_path? && add_path_segment?
end

#has_param?Boolean

Returns:

  • (Boolean)


75
76
77
78
79
80
81
# File 'lib/jets/router/route/node.rb', line 75

def has_param?
  return false if scope.root?

  resolved_param && param_action? ||
  scope.resource_descendent? && !leaf? ||
  scope.resource_sibling? && !leaf?
end

#has_path?Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/jets/router/route/node.rb', line 71

def has_path?
  scope.resolved_path && !scope.virtual?
end

#leaf?Boolean

Returns:

  • (Boolean)


104
105
106
# File 'lib/jets/router/route/node.rb', line 104

def leaf?
  scope == leaf_scope
end

#lookahead_shallow?(parent: false) ⇒ Boolean

Returns:

  • (Boolean)


59
60
61
62
63
64
65
66
67
68
69
# File 'lib/jets/router/route/node.rb', line 59

def lookahead_shallow?(parent: false)
  next_scope = scope
  while next_scope
    check_scope = parent ? next_scope.parent : next_scope
    # Important to check next_scope == leaf_scope
    # Otherwise it'll collapse path segments for higher scopes also.
    return true if check_scope.shallow? && next_scope == leaf_scope
    next_scope = next_scope.next
  end
  false
end

#paramObject

If a block has pass then we assume the resources will be nested and then prefix the param name with the resource. IE: post_id instead of id This avoids an API Gateway parent sibling variable collision.



124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/jets/router/route/node.rb', line 124

def param
  return scope.options[:param] if scope.options[:param]

  if leaf? && Jets.config.routes.allow_sibling_conflicts
    "id"
  elsif scope.resource_descendent? ||
        scope.resource_sibling? && scope.colliding_resource_sibling?
    "#{scope.resource_name.to_s.singularize}_id"
  else
    "id"
  end
end

#param_action?Boolean

Returns:

  • (Boolean)


94
95
96
97
# File 'lib/jets/router/route/node.rb', line 94

def param_action?
  @options[:on] == :member || scope.from == :member ||
  %w[edit show update destroy].include?(@info.action)
end

#paramless_action?Boolean

Returns:

  • (Boolean)


99
100
101
102
# File 'lib/jets/router/route/node.rb', line 99

def paramless_action?
  @options[:on] == :collection || scope.from == :collection ||
  %w[index new create].include?(@info.action)
end

#resolved_asObject



83
84
85
86
87
88
89
90
91
92
# File 'lib/jets/router/route/node.rb', line 83

def resolved_as
  as = scope.as || scope.resource_name
  # as = scope.as || scope.resource_name
  if scope.resource_name
    controller = nil # dont need controller. can infer from resources, namespace, etc
  else # direct route method without scope or module only etc
    controller = @info.controller.split('/').last if leaf? #&& as.nil?
  end
  [as, controller].compact.join('_')
end

#resolved_paramObject



112
113
114
115
116
117
118
119
# File 'lib/jets/router/route/node.rb', line 112

def resolved_param
  case scope.from
  when :resources, :member
    ":#{param}"
  else # :resource, :namespace, :path, :collection
    nil
  end
end

#resolved_pathObject



108
109
110
# File 'lib/jets/router/route/node.rb', line 108

def resolved_path
  scope.resolved_path
end

#shallow_param_action?Boolean

Returns:

  • (Boolean)


51
52
53
# File 'lib/jets/router/route/node.rb', line 51

def shallow_param_action?
  lookahead_shallow? || leaf_scope.any_parent_shallow?
end

#shallow_paramless_action?Boolean

Returns:

  • (Boolean)


55
56
57
# File 'lib/jets/router/route/node.rb', line 55

def shallow_paramless_action?
  lookahead_shallow?(parent: true) || scope.any_parent_shallow?
end