Class: Merb::Router::Route

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(conditions, params, behavior = nil, &conditional_block) ⇒ Route

Parameters

conditions<Hash>

Conditions for the route.

params<Hash>

Parameters for the route.

behavior<Merb::Router::Behavior>

The associated behavior. Defaults to nil.

&conditional_block

A block with the conditions to be met for the route to take effect.



17
18
19
20
21
22
23
# File 'lib/merb-core/dispatch/router/route.rb', line 17

def initialize(conditions, params, behavior = nil, &conditional_block)
  @conditions, @params, @behavior = conditions, params, behavior
  @conditional_block = conditional_block
  if @behavior && (path = @behavior.merged_original_conditions[:path])
    @segments = segments_from_path(path)
  end
end

Instance Attribute Details

#behaviorObject (readonly)

Returns the value of attribute behavior.



8
9
10
# File 'lib/merb-core/dispatch/router/route.rb', line 8

def behavior
  @behavior
end

#conditional_blockObject (readonly)

Returns the value of attribute conditional_block.



7
8
9
# File 'lib/merb-core/dispatch/router/route.rb', line 7

def conditional_block
  @conditional_block
end

#conditionsObject (readonly)

Returns the value of attribute conditions.



7
8
9
# File 'lib/merb-core/dispatch/router/route.rb', line 7

def conditions
  @conditions
end

#indexObject (readonly)

Returns the value of attribute index.



8
9
10
# File 'lib/merb-core/dispatch/router/route.rb', line 8

def index
  @index
end

#paramsObject (readonly)

Returns the value of attribute params.



8
9
10
# File 'lib/merb-core/dispatch/router/route.rb', line 8

def params
  @params
end

#segmentsObject (readonly)

Returns the value of attribute segments.



8
9
10
# File 'lib/merb-core/dispatch/router/route.rb', line 8

def segments
  @segments
end

#symbolObject (readonly)

Returns the value of attribute symbol.



8
9
10
# File 'lib/merb-core/dispatch/router/route.rb', line 8

def symbol
  @symbol
end

Instance Method Details

#allow_fixation?Boolean

Returns

Boolean

True if fixation is allowed.

Returns:

  • (Boolean)


27
28
29
# File 'lib/merb-core/dispatch/router/route.rb', line 27

def allow_fixation? 
  @fixation
end

#behavior_traceObject

Prints a trace of the behavior for this route.



203
204
205
206
207
208
209
# File 'lib/merb-core/dispatch/router/route.rb', line 203

def behavior_trace
  if @behavior
    puts @behavior.send(:ancestors).reverse.map{|a| a.inspect}.join("\n"); puts @behavior.inspect; puts
  else
    puts "No behavior to trace #{self}"
  end
end

#compile(first = false) ⇒ Object

Compiles the route to a form used by Merb::Router.

Parameters

first<Boolean>

True if this is the first route in set of routes. Defaults to false.

Returns

String

The code corresponding to the route in a form suited for eval.



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/merb-core/dispatch/router/route.rb', line 180

def compile(first = false)
  code = ""
  default_params = { :action => "index" }
  get_value = proc do |key|
    if default_params.has_key?(key) && params[key][0] != ?"
      "#{params[key]} || \"#{default_params[key]}\""
    else
      "#{params[key]}"
    end
  end
  params_as_string = params.keys.map { |k| "#{k.inspect} => #{get_value[k]}" }.join(', ')
  code << "  els" unless first
  code << "if  # #{@behavior.merged_original_conditions.inspect}  \n"
  code << if_conditions(params_as_string).join(" && ") << "\n"
  code << "    # then\n"
  if @conditional_block
    code << "    [#{@index.inspect}, block_result]\n"
  else
    code << "    [#{@index.inspect}, {#{params_as_string}}]\n"
  end
end

#fixatable(enable = true) ⇒ Object

Parameters

enabled<Boolean>

True enables fixation on the route.



33
34
35
36
# File 'lib/merb-core/dispatch/router/route.rb', line 33

def fixatable(enable=true) 
  @fixation = enable 
  self
end

#generate(params = {}, fallback = {}) ⇒ Object

Parameters

params<Hash>

Optional parameters for the route.

fallback<Hash>

Optional parameters for the fallback route.

Returns

String

The URL corresponding to the params, using the stored route segments for reconstruction of the URL.



108
109
110
111
112
113
114
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
# File 'lib/merb-core/dispatch/router/route.rb', line 108

def generate(params = {}, fallback = {})
  raise "Cannot generate regexp Routes" if regexp?
  query_params = params.dup if params.is_a? Hash
  url = @segments.map do |segment|
    value =
      if segment.is_a? Symbol
        if params.is_a? Hash
          params[segment] || fallback[segment]
          query_params.delete segment
        else
          if segment == :id && params.respond_to?(:to_param) 
            params.to_param
          elsif segment == :id && params.is_a?(Fixnum)
            params
          elsif params.respond_to?(segment)
            params.send(segment)
          else
            fallback[segment]
          end
        end
      elsif segment.respond_to? :to_s
        segment
      else
        raise "Segment type '#{segment.class}' can't be converted to a string"
      end
    (value.respond_to?(:to_param) ? value.to_param : value).to_s
  end.join
  if query_params && !query_params.empty?
    url += "?" + Merb::Request.params_to_query_string(query_params)
  end
  url
end

#if_conditions(params_as_string) ⇒ Object

Params

params_as_string<String>

The params hash as a string, e.g. “:foo => ‘bar’”.

Returns

Array

All the conditions as eval’able strings.



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/merb-core/dispatch/router/route.rb', line 147

def if_conditions(params_as_string)
  cond = []
  condition_string = proc do |key, value, regexp_string|
    max = Behavior.count_parens_up_to(value.source, value.source.size)
    captures = max == 0 ? "" : (1..max).to_a.map{ |n| "#{key}#{n}" }.join(", ") + " = " +
                               (1..max).to_a.map{ |n| "$#{n}"}.join(", ")
    " (#{value.inspect} =~ #{regexp_string}) #{" && (" + captures + ")" unless captures.empty?}"
  end
  @conditions.each_pair do |key, value|
    
    # Note: =~ is slightly faster than .match
    cond << case key
    when :path then condition_string[key, value, "cached_path"]
    when :method then condition_string[key, value, "cached_method"]
    else condition_string[key, value, "request.#{key}.to_s"]
    end
  end
  if @conditional_block
    str = "  # #{@conditional_block.inspect.scan(/@([^>]+)/).flatten.first}\n"
    str << "    (block_result = #{CachedProc.new(@conditional_block)}.call(request, params.merge({#{params_as_string}})))" if @conditional_block
    cond << str
  end
  cond
end

#name(symbol = nil) ⇒ Object

Names this route in Router.

Parameters

symbol<Symbol>

The name of the route.

Raises

ArgumentError

symbol is not a Symbol.

Raises:

  • (ArgumentError)


87
88
89
90
# File 'lib/merb-core/dispatch/router/route.rb', line 87

def name(symbol = nil)
  raise ArgumentError unless (@symbol = symbol).is_a?(Symbol)
  Router.named_routes[@symbol] = self
end

#regexp?Boolean

Returns

Boolean

True if this route is a regexp, i.e. its behavior or one of the behaviors ancestors is a regexp.

Returns:

  • (Boolean)


96
97
98
# File 'lib/merb-core/dispatch/router/route.rb', line 96

def regexp?
  behavior.regexp? || behavior.send(:ancestors).any? { |a| a.regexp? }
end

#registerObject

Registers the route in the Router.routes array.



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

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

#segments_from_path(path) ⇒ Object

Turn a path into string and symbol segments so it can be reconstructed, as in the case of a named route.

Parameters

path<String>

The path to split into segments.

Returns

Array

The Symbol and String segments for the path.



67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/merb-core/dispatch/router/route.rb', line 67

def segments_from_path(path)
  # Remove leading ^ and trailing $ from each segment (left-overs from regexp joining)
  strip = proc { |str| str.gsub(/^\^/, '').gsub(/\$$/, '') }
  segments = []
  while match = (path.match(SEGMENT_REGEXP))
    segments << strip[match.pre_match] unless match.pre_match.empty?
    segments << match[2].intern
    path = strip[match.post_match]
  end
  segments << strip[path] unless path.empty?
  segments
end

#symbol_segmentsObject

Returns

Array

All the symbols in the segments array.



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

def symbol_segments
  segments.select{ |s| s.is_a?(Symbol) }
end

#to_sObject

Returns

String

The route as a string, e.g. “admin/:controller/:id”.



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

def to_s
  segments.inject('') do |str,seg|
    str << (seg.is_a?(Symbol) ? ":#{seg}" : seg)
  end
end