Class: Sinatra::AcceptParams::ParamRules

Inherits:
Object
  • Object
show all
Defined in:
lib/sinatra/accept_params/param_rules.rb

Overview

This class is used to declare the structure of the params hash for this request.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(settings, type = nil, name = nil, options = {}, parent = nil) ⇒ ParamRules

TODO: Convert this to a hash of options.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/sinatra/accept_params/param_rules.rb', line 9

def initialize(settings, type=nil, name=nil, options={}, parent=nil) # :nodoc:
  if (name.nil? && !parent.nil?) || (parent.nil? && !name.nil?)
    raise ArgumentError, "parent and name must both be either nil or not nil"
  end
  if (name.nil? && !type.nil?) || (type.nil? && !name.nil?)
    raise ArgumentError, "type and name must both be either nil or not nil"
  end
  @type     = type
  @parent   = parent
  @children = []
  @options  = options

  # Set default options which control behavior
  @settings = {
    :ignore_unexpected => AcceptParams.ignore_unexpected,
    :remove_unexpected => AcceptParams.remove_unexpected,
    :ignore_params     => AcceptParams.ignore_params,
    :ignore_columns    => AcceptParams.ignore_columns,
    :ssl_enabled       => AcceptParams.ssl_enabled
  }.merge(settings)

  # This is needed for resource_definitions
  @settings[:indent] ||= 0
  @settings[:indent] += 2

  if name.nil?
    @name = nil
  elsif is_model?(name)
    klass = name
    @name = klass.to_s.underscore
    is_a klass
  else
    @name = name.to_s
  end

  # This is undocumented, and specific to SCEA
  if @options.has_key? :to_id
    klass = @options[:to_id]
    @options[:process] = Proc.new{|v| klass.to_id(v)}
    @options[:to] = "#{@name}_id"
  end
end

Instance Attribute Details

#childrenObject (readonly)

:nodoc:



6
7
8
# File 'lib/sinatra/accept_params/param_rules.rb', line 6

def children
  @children
end

#definitionObject (readonly)

:nodoc:



6
7
8
# File 'lib/sinatra/accept_params/param_rules.rb', line 6

def definition
  @definition
end

#nameObject (readonly)

:nodoc:



6
7
8
# File 'lib/sinatra/accept_params/param_rules.rb', line 6

def name
  @name
end

#optionsObject (readonly)

:nodoc:



6
7
8
# File 'lib/sinatra/accept_params/param_rules.rb', line 6

def options
  @options
end

#parentObject (readonly)

:nodoc:



6
7
8
# File 'lib/sinatra/accept_params/param_rules.rb', line 6

def parent
  @parent
end

#settingsObject (readonly)

:nodoc:



6
7
8
# File 'lib/sinatra/accept_params/param_rules.rb', line 6

def settings
  @settings
end

#typeObject (readonly)

:nodoc:



6
7
8
# File 'lib/sinatra/accept_params/param_rules.rb', line 6

def type
  @type
end

Instance Method Details

#array(name, options = {}) ⇒ Object



112
113
114
# File 'lib/sinatra/accept_params/param_rules.rb', line 112

def array(name, options={})
  param(:array, name, options)
end

#binary(name, options = {}) ⇒ Object



109
110
111
# File 'lib/sinatra/accept_params/param_rules.rb', line 109

def binary(name, options={})
  param(:binary, name, options)
end

#boolean(name, options = {}) ⇒ Object



100
101
102
# File 'lib/sinatra/accept_params/param_rules.rb', line 100

def boolean(name, options={})
  param(:boolean, name, options)
end

#canonical_nameObject

Returns the full name of this parameter as it would be accessed in the action. Example output might be “params[:name]”.



143
144
145
146
147
148
149
150
151
# File 'lib/sinatra/accept_params/param_rules.rb', line 143

def canonical_name #:nodoc:
  if parent.nil?
    ""
  elsif parent.parent.nil?
    name
  else
    parent.canonical_name + "[#{name}]" 
  end
end

#datetime(name, options = {}) ⇒ Object



103
104
105
# File 'lib/sinatra/accept_params/param_rules.rb', line 103

def datetime(name, options={})
  param(:datetime, name, options)
end

#decimal(name, options = {}) ⇒ Object



97
98
99
# File 'lib/sinatra/accept_params/param_rules.rb', line 97

def decimal(name, options={})
  param(:decimal, name, options)
end

#file(name, options = {}) ⇒ Object



115
116
117
# File 'lib/sinatra/accept_params/param_rules.rb', line 115

def file(name, options={})
  param(:file, name, options)
end

#float(name, options = {}) ⇒ Object



94
95
96
# File 'lib/sinatra/accept_params/param_rules.rb', line 94

def float(name, options={})
  param(:float, name, options)
end

#integer(name, options = {}) ⇒ Object



91
92
93
# File 'lib/sinatra/accept_params/param_rules.rb', line 91

def integer(name, options={})
  param(:integer, name, options)
end

#model(klass) ⇒ Object

This is a shortcut for declaring elements that represent ActiveRecord classes. Essentially, it creates a declaration for each attribute of the given model (excluding the ones in the class attribute ignore_columns, which is described at the top of this page).



123
124
125
126
127
128
129
130
# File 'lib/sinatra/accept_params/param_rules.rb', line 123

def model(klass)
  unless is_model?(klass)
    raise ArgumentError, "Must supply an ActiveRecord class to the model method"
  end
  klass.columns.each do |c|
    param(c.type, c.name, :required => !c.null, :limit => c.limit) unless ignore_column?(c)
  end
end

#namespace(name) {|child| ... } ⇒ Object

Allow nesting

Yields:

  • (child)

Raises:

  • (ArgumentError)


80
81
82
83
84
85
# File 'lib/sinatra/accept_params/param_rules.rb', line 80

def namespace(name, &block)
  raise ArgumentError, "Missing block to param namespace declaration" unless block_given?
  child = ParamRules.new(settings, :namespace, name, {:required => false}, self)  # block not required per se
  yield child
  @children << child
end

#namespace?Boolean

Returns:

  • (Boolean)


137
138
139
# File 'lib/sinatra/accept_params/param_rules.rb', line 137

def namespace?
  type == :namespace
end

#param(type, name, options) ⇒ Object

Create a new param



175
176
177
# File 'lib/sinatra/accept_params/param_rules.rb', line 175

def param(type, name, options)
  @children << ParamRules.new(settings, type.to_sym, name, options, self)
end

#required?Boolean

Is this a required params element? Implies “must_have”.

Returns:

  • (Boolean)


133
134
135
# File 'lib/sinatra/accept_params/param_rules.rb', line 133

def required? #:nodoc:
  options[:required]
end

#string(name, options = {}) ⇒ Object

Ala pretty migrations



88
89
90
# File 'lib/sinatra/accept_params/param_rules.rb', line 88

def string(name, options={})
  param(:string, name, options)
end

#text(name, options = {}) ⇒ Object



106
107
108
# File 'lib/sinatra/accept_params/param_rules.rb', line 106

def text(name, options={})
  param(:text, name, options)
end

#validate(params) ⇒ Object

Validate the given parameters against our requirements, raising exceptions for missing or unexpected parameters.



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/sinatra/accept_params/param_rules.rb', line 155

def validate(params) #:nodoc:
  recognized_keys = validate_children(params)
  unexpected_keys = params.keys - recognized_keys
  if parent.nil?
    # Only ignore the standard params at the top level.
    unexpected_keys -= settings[:ignore_params]
  end
  unless unexpected_keys.empty?
    # kinda hacky to get it to display correctly
    unless settings[:ignore_unexpected]
      basename   = canonical_name
      canonicals = unexpected_keys.sort.collect{|k| basename.empty? ? k : basename + "[#{k}]"}.join(', ')
      s = unexpected_keys.length == 1 ? '' : 's'
      raise UnexpectedParam, "Request included unexpected parameter#{s}: #{canonicals}"
    end
    unexpected_keys.each{|k| params.delete(k)} if settings[:remove_unexpected]
  end
end

#validate_request(request, session) ⇒ Object

Validate the request object, checking the :ssl and :login flags This needs a big refactor, this whole class is DOG SLOW



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/sinatra/accept_params/param_rules.rb', line 54

def validate_request(request, session)
  unless @settings[:ssl_enabled] == false or ENV['RACK_ENV'] == 'development'
    if @settings[:ssl]
      # explicitly said :ssl => true
      raise SslRequired unless request.secure?
    elsif @settings.has_key?(:ssl)
      # explicitly said :ssl => false or :ssl => nil, so skip
    else
      # require SSL on anything non-GET
      raise SslRequired unless request.get?
    end
  end
  
  # Same thing for login_required, minus global flag
  if @settings[:login]
    # explicitly said :login => true
    raise LoginRequired unless session[:username]
  elsif @settings.has_key?(:login)
    # explicitly said :login => false or :login => nil, so skip
  else
    # require login on anything non-GET
    raise LoginRequired unless session[:username] || request.get?
  end
end