Class: Merb::Router::Route

Inherits:
Object show all
Defined in:
lib/merb-core/dispatch/router/route.rb

Overview

This entire class is private and should never be accessed outside of Merb::Router and Behavior

Defined Under Namespace

Classes: Generator

Constant Summary collapse

SEGMENT_REGEXP =

:nodoc:

/(:([a-z](_?[a-z0-9])*))/
OPTIONAL_SEGMENT_REGEX =
/^.*?([\(\)])/i
SEGMENT_REGEXP_WITH_BRACKETS =
/(:[a-z_]+)(\[(\d+)\])?/
JUST_BRACKETS =
/\[(\d+)\]/
SEGMENT_CHARACTERS =
"[^\/.,;?]".freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(conditions, params, deferred_procs, options = {}) ⇒ Route

Returns a new instance of Route.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/merb-core/dispatch/router/route.rb', line 17

def initialize(conditions, params, deferred_procs, options = {})
  @conditions, @params = conditions, params

  if options[:redirects]
    @redirects         = true
    @redirect_status   = @params[:status]
    @redirect_url      = @params[:url]
    @defaults          = {}
  else
    @defaults          = options[:defaults] || {}
  end
  
  # @conditional_block = conditional_block

  @identifiers       = options[:identifiers]
  @deferred_procs    = deferred_procs
  @segments          = []
  @symbol_conditions = {}
  @placeholders      = {}
  compile
end

Instance Attribute Details

#conditionsObject (readonly)

Returns the value of attribute conditions.



13
14
15
# File 'lib/merb-core/dispatch/router/route.rb', line 13

def conditions
  @conditions
end

#fixationObject

Returns the value of attribute fixation.



15
16
17
# File 'lib/merb-core/dispatch/router/route.rb', line 15

def fixation
  @fixation
end

#indexObject (readonly)

Returns the value of attribute index.



14
15
16
# File 'lib/merb-core/dispatch/router/route.rb', line 14

def index
  @index
end

#nameObject

Returns the value of attribute name.



14
15
16
# File 'lib/merb-core/dispatch/router/route.rb', line 14

def name
  @name
end

#paramsObject (readonly)

Returns the value of attribute params.



13
14
15
# File 'lib/merb-core/dispatch/router/route.rb', line 13

def params
  @params
end

#segmentsObject (readonly)

Returns the value of attribute segments.



13
14
15
# File 'lib/merb-core/dispatch/router/route.rb', line 13

def segments
  @segments
end

#variablesObject (readonly)

Returns the value of attribute variables.



14
15
16
# File 'lib/merb-core/dispatch/router/route.rb', line 14

def variables
  @variables
end

Instance Method Details

#allow_fixation?Boolean

Returns:

  • (Boolean)


43
44
45
# File 'lib/merb-core/dispatch/router/route.rb', line 43

def allow_fixation?
  @fixation
end

#compiled_statement(first) ⇒ Object

Returns the if statement and return value for for the main Router.match compiled method.



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/merb-core/dispatch/router/route.rb', line 172

def compiled_statement(first)
  els_if = first ? '  if ' : '  elsif '

  code = ""
  code << els_if << condition_statements.join(" && ") << "\n"
  
  # First, we need to always return the value of the
  # deferred block if it explicitly matched the route
  if @redirects
    code << "    return [#{@index.inspect}, block_result] if request.matched?" << "\n" if @deferred_procs.any?
    code << "    [#{@index.inspect}, Merb::Rack::Helpers.redirect(#{@redirect_url.inspect}, :status => #{@redirect_status.inspect})]" << "\n"
  elsif @deferred_procs.any?
    code << "    [#{@index.inspect}, block_result]" << "\n"
  else
    code << "    [#{@index.inspect}, #{params_as_string}]" << "\n"
  end
end

#generate(args = [], defaults = {}) ⇒ Object

Generates the URL for the route given the passed arguments. The method will first match the anonymous parameters to route params and will convert all the parameters according to the specifed object identifiers.

Then the named parameters are passed to a compiled generation proc.

Parameters

args<Array>

The arguments passed to the public #url method with the name of the route removed. This is an array of the anonymous parameters followed by a hash containing the named parameters.

defaults<Hash>

A hash of parameters to use to generate the route if there are any missing required parameters. This is usually the parameters for the current request

Returns

String

The generated URL.

Raises:



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/merb-core/dispatch/router/route.rb', line 102

def generate(args = [], defaults = {})
  raise GenerationError, "Cannot generate regexp Routes" if regexp?
  
  params = extract_options_from_args!(args) || { }
  
  params.each do |k, v|
    params[k] = identify(v, k)
  end
  
  # Support for anonymous params
  unless args.empty?
    # First, let's determine which variables are missing
    variables = @variables - params.keys
    
    args.each do |param|
      raise GenerationError, "The route has #{@variables.length} variables: #{@variables.inspect}" if variables.empty?
      
      if identifier = identifier_for(param) and identifier.is_a?(Array)
        identifier.each { |ident| params[variables.shift] = param.send(ident) }
      else
        params[variables.shift] ||= identify(param)
      end
    end
  end
  
  uri = @generator[params, defaults] or raise GenerationError, "Named route #{name} could not be generated with #{params.inspect}"
  uri = Merb::Config[:path_prefix] + uri if Merb::Config[:path_prefix]
  uri
end

#identifier_for(obj) ⇒ Object

Returns the identifier for the passed object. Built in core ruby classes are always identified with to_s. The method will return nil in that case (since to_s is the default for objects that do not have identifiers.)



158
159
160
161
162
163
164
165
166
167
168
# File 'lib/merb-core/dispatch/router/route.rb', line 158

def identifier_for(obj)
  return if obj.is_a?(String)    || obj.is_a?(Symbol)     || obj.is_a?(Numeric)  ||
            obj.is_a?(TrueClass) || obj.is_a?(FalseClass) || obj.is_a?(NilClass) ||
            obj.is_a?(Array)     || obj.is_a?(Hash)
  
  @identifiers.each do |klass, identifier|
    return identifier if obj.is_a?(klass)
  end
  
  return nil
end

#identify(obj, param_key = nil) ⇒ Object

Identifies the object according to the identifiers set while building the routes. Identifying an object means picking an instance method to call on the object that will return a string representation of the object for the route being generated. If the identifier is an array, then a param_key must be present and match one of the elements of the identifier array.

param_keys that end in _id are treated slightly differently in order to get nested resources to work correctly.



141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/merb-core/dispatch/router/route.rb', line 141

def identify(obj, param_key = nil)
  identifier = identifier_for(obj)
  if identifier.is_a?(Array)
    # First check if the param_key exists as an identifier
    return obj.send(param_key) if identifier.include?(param_key)
    # If the param_key ends in _id, just return the object id
    return obj.id if "#{param_key}" =~ /_id$/
    # Otherwise, raise an error
    raise GenerationError, "The object #{obj.inspect} cannot be identified with #{identifier.inspect} for #{param_key}"
  else
    identifier ? obj.send(identifier) : obj
  end
end

#regexp?Boolean

Returns:

  • (Boolean)


39
40
41
# File 'lib/merb-core/dispatch/router/route.rb', line 39

def regexp?
  @regexp
end

#registerObject

Appends self to Merb::Router.routes



56
57
58
59
60
# File 'lib/merb-core/dispatch/router/route.rb', line 56

def register
  @index = Merb::Router.routes.size
  Merb::Router.routes << self
  self
end

#register_at(index) ⇒ Object

Inserts self to Merb::Router.routes at the specified index.



63
64
65
66
67
# File 'lib/merb-core/dispatch/router/route.rb', line 63

def register_at(index)
  @index = index
  Merb::Router.routes.insert(index, self)
  self
end

#resource=(key) ⇒ Object

Sets the route as a resource route with the given key as the lookup key.



71
72
73
74
# File 'lib/merb-core/dispatch/router/route.rb', line 71

def resource=(key)
  Router.resource_routes[key] = self
  key
end

#to_sObject Also known as: inspect



47
48
49
50
51
# File 'lib/merb-core/dispatch/router/route.rb', line 47

def to_s
  regexp? ?
    "/#{conditions[:path].source}/" :
    segment_level_to_s(segments)
end