Class: ActionController::Routing::DynamicSegment

Inherits:
Segment show all
Defined in:
lib/action_controller/routing/segments.rb

Overview

:nodoc:

Direct Known Subclasses

ControllerSegment, PathSegment

Constant Summary

Constants inherited from Segment

Segment::RESERVED_PCHAR, Segment::SAFE_PCHAR, Segment::UNSAFE_PCHAR

Instance Attribute Summary collapse

Attributes inherited from Segment

#is_optional

Instance Method Summary collapse

Methods inherited from Segment

#all_optionals_available_condition, #continue_string_structure, #interpolation_statement

Constructor Details

#initialize(key = nil, options = {}) ⇒ DynamicSegment

Returns a new instance of DynamicSegment.


131
132
133
134
135
136
137
# File 'lib/action_controller/routing/segments.rb', line 131

def initialize(key = nil, options = {})
  super()
  @key = key
  @default = options[:default] if options.key?(:default)
  @regexp = options[:regexp] if options.key?(:regexp)
  @is_optional = true if options[:optional] || options.key?(:default)
end

Instance Attribute Details

#defaultObject

TODO: Convert these accessors to read only


129
130
131
# File 'lib/action_controller/routing/segments.rb', line 129

def default
  @default
end

#keyObject (readonly)

Returns the value of attribute key


126
127
128
# File 'lib/action_controller/routing/segments.rb', line 126

def key
  @key
end

#regexpObject

TODO: Convert these accessors to read only


129
130
131
# File 'lib/action_controller/routing/segments.rb', line 129

def regexp
  @regexp
end

Instance Method Details

#build_pattern(pattern) ⇒ Object


213
214
215
216
# File 'lib/action_controller/routing/segments.rb', line 213

def build_pattern(pattern)
  pattern = "#{regexp_chunk}#{pattern}"
  optional? ? Regexp.optionalize(pattern) : pattern
end

#default_regexp_chunkObject


205
206
207
# File 'lib/action_controller/routing/segments.rb', line 205

def default_regexp_chunk
  "([^#{Routing::SEPARATORS.join}]+)"
end

#expiry_statementObject


164
165
166
# File 'lib/action_controller/routing/segments.rb', line 164

def expiry_statement
  "expired, hash = true, options if !expired && expire_on[:#{key}]"
end

#extract_valueObject


148
149
150
# File 'lib/action_controller/routing/segments.rb', line 148

def extract_value
  "#{local_name} = hash[:#{key}] && hash[:#{key}].to_param #{"|| #{default.inspect}" if default}"
end

#extraction_codeObject


168
169
170
171
172
173
# File 'lib/action_controller/routing/segments.rb', line 168

def extraction_code
  s = extract_value
  vc = value_check
  s << "\nreturn [nil,nil] unless #{vc}" if vc
  s << "\n#{expiry_statement}"
end

#interpolation_chunk(value_code = local_name) ⇒ Object


175
176
177
# File 'lib/action_controller/routing/segments.rb', line 175

def interpolation_chunk(value_code = local_name)
  "\#{URI.escape(#{value_code}.to_s, ActionController::Routing::Segment::UNSAFE_PCHAR)}"
end

#local_nameObject

The local variable name that the value of this segment will be extracted to.


144
145
146
# File 'lib/action_controller/routing/segments.rb', line 144

def local_name
  "#{key}_value"
end

#match_extraction(next_capture) ⇒ Object


218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/action_controller/routing/segments.rb', line 218

def match_extraction(next_capture)
  # All non code-related keys (such as :id, :slug) are URI-unescaped as
  # path parameters.
  default_value = default ? default.inspect : nil
  %[
    value = if (m = match[#{next_capture}])
      URI.unescape(m)
    else
      #{default_value}
    end
    params[:#{key}] = value if value
  ]
end

#number_of_capturesObject


209
210
211
# File 'lib/action_controller/routing/segments.rb', line 209

def number_of_captures
  regexp ? regexp.number_of_captures + 1 : 1
end

#optionality_implied?Boolean

Returns:

  • (Boolean)

232
233
234
# File 'lib/action_controller/routing/segments.rb', line 232

def optionality_implied?
  [:action, :id].include? key
end

#regexp_chunkObject


197
198
199
# File 'lib/action_controller/routing/segments.rb', line 197

def regexp_chunk
  regexp ? regexp_string : default_regexp_chunk
end

#regexp_has_modifiers?Boolean

Returns:

  • (Boolean)

236
237
238
# File 'lib/action_controller/routing/segments.rb', line 236

def regexp_has_modifiers?
  regexp.options & (Regexp::IGNORECASE | Regexp::EXTENDED) != 0
end

#regexp_stringObject


201
202
203
# File 'lib/action_controller/routing/segments.rb', line 201

def regexp_string
  regexp_has_modifiers? ? "(#{regexp.to_s})" : "(#{regexp.source})"
end

#string_structure(prior_segments) ⇒ Object


179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/action_controller/routing/segments.rb', line 179

def string_structure(prior_segments)
  if optional? # We have a conditional to do...
    # If we should not appear in the url, just write the code for the prior
    # segments. This occurs if our value is the default value, or, if we are
    # optional, if we have nil as our value.
    "if #{local_name} == #{default.inspect}\n" +
      continue_string_structure(prior_segments) +
    "\nelse\n" + # Otherwise, write the code up to here
      "#{interpolation_statement(prior_segments)}\nend"
  else
    interpolation_statement(prior_segments)
  end
end

#to_sObject


139
140
141
# File 'lib/action_controller/routing/segments.rb', line 139

def to_s
  ":#{key}"
end

#value_checkObject


152
153
154
155
156
157
158
159
160
161
162
# File 'lib/action_controller/routing/segments.rb', line 152

def value_check
  if default # Then we know it won't be nil
    "#{value_regexp.inspect} =~ #{local_name}" if regexp
  elsif optional?
    # If we have a regexp check that the value is not given, or that it matches.
    # If we have no regexp, return nil since we do not require a condition.
    "#{local_name}.nil? || #{value_regexp.inspect} =~ #{local_name}" if regexp
  else # Then it must be present, and if we have a regexp, it must match too.
    "#{local_name} #{"&& #{value_regexp.inspect} =~ #{local_name}" if regexp}"
  end
end

#value_regexpObject


193
194
195
# File 'lib/action_controller/routing/segments.rb', line 193

def value_regexp
  Regexp.new "\\A#{regexp.to_s}\\Z" if regexp
end