Module: DuckMap::RouteSet

Extended by:
ActiveSupport::Concern
Defined in:
lib/duck_map/route_set.rb

Overview

Mixin module for ActionDispatch::Routing::RouteSet to add support for defining sitemaps directly inside the config/routes.rb of a Rails app.

Instance Method Summary collapse

Instance Method Details

#find_route_via_name(name) ⇒ Object



151
152
153
# File 'lib/duck_map/route_set.rb', line 151

def find_route_via_name(name)
  return self.routes.find {|route| route.name.eql?(name)}
end

#find_route_via_path(path, environment = {}) ⇒ Object

Raises:

  • (ActionController::RoutingError)


156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/duck_map/route_set.rb', line 156

def find_route_via_path(path, environment = {})
  method = (environment[:method] || "GET").to_s.upcase
  path = ActionDispatch::Journey::Router::Utils.normalize_path(path) unless path =~ %r{://}

  begin
    env = Rack::MockRequest.env_for(path, {:method => method})
  rescue URI::InvalidURIError => e
    raise ActionController::RoutingError, e.message
  end

  req = @request_class.new(env)
  @router.recognize(req) do |route, matches, params|
    params.each do |key, value|
      if value.is_a?(String)
        value = value.dup.force_encoding(Encoding::BINARY)# if value.encoding_aware?
        params[key] = URI.parser.unescape(value)
      end
    end

    dispatcher = route.app

    while dispatcher.is_a?(ActionDispatch::Routing::Mapper::Constraints) && dispatcher.matches?(env) do
      dispatcher = dispatcher.app
    end

    if dispatcher.is_a?(ActionDispatch::Routing::RouteSet::Dispatcher) && dispatcher.controller(params, false)
      dispatcher.prepare_params!(params)
      return route
    end
  end

  raise ActionController::RoutingError, "No route matches #{path.inspect}"
end

#find_sitemap_route(name_or_path) ⇒ Array

Note:

See Mapper#sitemap for a full explanation of how to define a sitemap and how those rules affect this method.

Builds a list of routes associated with a sitemap. The actual list of routes returned is based on sitemap_route_name, which is the named route of the sitemap.

Parameters:

  • name_or_path (String)

    The request.path of the current sitemap url or the name assigned to the sitemap via config/routes.rb.

Returns:

  • (Array)


17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/duck_map/route_set.rb', line 17

def find_sitemap_route(name_or_path)

  name_or_path = name_or_path.to_s

  # strip off the extension if it exists
  if name_or_path.include?(".")
    name_or_path = name_or_path.slice(0, name_or_path.rindex("."))
  end

  full_name = "#{name_or_path}_sitemap"

  # search for a sitemap route matching the path passed to the method.
  # the route MUST be marked as a sitemap.  return nothing if the sitemap route cannot be found.
  return self.routes.find {|route| route.is_sitemap? &&
                                (route.path.spec.to_s =~ /^#{name_or_path}/ ||
                                route.sitemap_route_name.eql?(name_or_path) ||
                                route.sitemap_route_name.eql?(full_name))}
end

#route_owner(route) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/duck_map/route_set.rb', line 115

def route_owner(route)
  value = nil

  potential_owners = self.routes.find_all {|route| route.is_sitemap?}
  potential_owners.sort! { |a,b| b.namespace_prefix_underscores <=> a.namespace_prefix_underscores}

  potential_owners.each do |owner|

    if (!route.sitemap_route_name.blank? && owner.sitemap_route_name.eql?(route.sitemap_route_name))
      value = owner
      break
    elsif !owner.namespace_prefix.blank? && route.name =~ /^#{owner.namespace_prefix}/
      value = owner
      break
    end

  end

  if value.blank?
    potential_owners.each do |owner|
      if owner.namespace_prefix.blank? && !owner.sitemap_with_block?
        value = owner
        break
      end
    end
  end

  return value
end

#sitemap_routes(sitemap_route) ⇒ Array

Note:

See Mapper#sitemap for a full explanation of how to define a sitemap and how those rules affect this method.

Builds a list of routes associated with a sitemap route. The actual list of routes returned is based on sitemap_route_name, which is the named route of the sitemap.

Parameters:

  • sitemap_route (String)

    A sitemap route.

Returns:

  • (Array)


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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/duck_map/route_set.rb', line 43

def sitemap_routes(sitemap_route)
  list = []

  if sitemap_route

    # if the sitemap defined within config/routes.rb included a block, then, return ALL of the rows associated with
    # sitemap route name.  Otherwise, return ALL routes that have NOT BEEN associated with any other sitemap.
    if sitemap_route.sitemap_with_block?

      # sitemap_route_name MUST MATCH
      #list = self.routes.find_all {|route| !route.is_sitemap? && route.sitemap_route_name.eql?(sitemap_route.sitemap_route_name)}
      list = self.routes.find_all do |route|
        !route.is_sitemap? && route.sitemap_route_name.eql?(sitemap_route.sitemap_route_name)
      end

    else

      candidates = self.routes.find_all {|route| !route.is_sitemap?}
      potential_owners = self.routes.find_all {|route| route.is_sitemap?}
      potential_owners.sort! { |a,b| b.namespace_prefix_underscores <=> a.namespace_prefix_underscores}

      candidates.each do |candidate|

        value = nil
        potential_owners.each do |owner|

          if (!candidate.sitemap_route_name.blank? && owner.sitemap_route_name.eql?(candidate.sitemap_route_name))

            value = owner
            break

          elsif (!owner.namespace_prefix.blank? &&
                  candidate.name =~ /^#{owner.namespace_prefix}/ &&
                  !owner.sitemap_with_block?)

            value = owner
            break
          end

          if value.blank?
            potential_owners.each do |owner|
              if (owner.namespace_prefix.blank? && !owner.sitemap_with_block?)

                value = owner
                break

              end
            end
          end

        end

        if !value.blank? && value.name.eql?(sitemap_route.name)
          list.push(candidate)
        end

      end

      list.reject! {|route| !self.include_route?(route)}

    end

  end

  list.reject! {|route| route.path.spec =~ %r{/rails/info/properties|^/assets}}
  list.reject! {|route| route.name.eql?("rails_info")}
  list.reject! {|route| !route.is_available?}

  return list
end

#sitemap_routes_onlyObject



146
147
148
# File 'lib/duck_map/route_set.rb', line 146

def sitemap_routes_only
  return self.routes.find_all {|route| route.is_sitemap?}
end