cowtech-rails 2.8.1.0 → 2.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/app/helpers/cowtech/ruby_on_rails/helpers/application_helper.rb +98 -98
- data/app/helpers/cowtech/ruby_on_rails/helpers/ar_crud_helper.rb +293 -293
- data/app/helpers/cowtech/ruby_on_rails/helpers/browser_helper.rb +62 -62
- data/app/helpers/cowtech/ruby_on_rails/helpers/format_helper.rb +31 -31
- data/app/helpers/cowtech/ruby_on_rails/helpers/mongoid_crud_helper.rb +222 -222
- data/app/helpers/cowtech/ruby_on_rails/helpers/validation_helper.rb +60 -60
- data/app/models/cowtech/ruby_on_rails/models/e_mail.rb +55 -49
- data/lib/cowtech.rb +15 -15
- data/lib/cowtech/extensions.rb +34 -34
- data/lib/cowtech/monkey_patches.rb +54 -54
- data/lib/cowtech/scheduler.rb +33 -33
- data/lib/cowtech/tasks/app.rake +102 -102
- data/lib/cowtech/tasks/log.rake +73 -73
- data/lib/cowtech/tasks/mongodb.rake +56 -56
- data/lib/cowtech/tasks/server.rake +96 -96
- data/lib/cowtech/tasks/sql.rake +105 -105
- data/lib/cowtech/version.rb +8 -9
- metadata +4 -4
@@ -5,73 +5,73 @@
|
|
5
5
|
#
|
6
6
|
|
7
7
|
module Cowtech
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
if rv[:agent].present? then
|
15
|
-
agent = rv[:agent].downcase
|
8
|
+
module RubyOnRails
|
9
|
+
module Helpers
|
10
|
+
module BrowserHelper
|
11
|
+
def browser_detect
|
12
|
+
rv = {:engine => :unknown, :version => "0", :platform => :unknown, :agent => request.user_agent || request.env['HTTP_USER_AGENT'].try(:downcase) || ""}
|
16
13
|
|
17
|
-
|
18
|
-
|
19
|
-
rv[:engine] = :opera
|
20
|
-
elsif agent =~ /webkit/ then
|
21
|
-
rv[:engine] = (agent =~ /chrome|chromium/ ? :chrome : :safari)
|
22
|
-
elsif agent =~ /msie/ || agent =~ /webtv/ then
|
23
|
-
rv[:engine] = :msie
|
24
|
-
elsif agent =~ /mozilla/ && agent !~ /compatible/ then
|
25
|
-
rv[:engine] = :mozilla
|
26
|
-
end
|
14
|
+
if rv[:agent].present? then
|
15
|
+
agent = rv[:agent].downcase
|
27
16
|
|
28
|
-
|
29
|
-
|
30
|
-
|
17
|
+
# Identify engine
|
18
|
+
if agent =~ /opera/ then
|
19
|
+
rv[:engine] = :opera
|
20
|
+
elsif agent =~ /webkit/ then
|
21
|
+
rv[:engine] = (agent =~ /chrome|chromium/ ? :chrome : :safari)
|
22
|
+
elsif agent =~ /msie/ || agent =~ /webtv/ then
|
23
|
+
rv[:engine] = :msie
|
24
|
+
elsif agent =~ /mozilla/ && agent !~ /compatible/ then
|
25
|
+
rv[:engine] = :mozilla
|
26
|
+
end
|
31
27
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
elsif agent =~ /macintosh|mac os x/ then
|
36
|
-
rv[:platform] = :mac
|
37
|
-
elsif agent =~ /windows|win32|win64/ then
|
38
|
-
rv[:platform] = :windows
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
@browser = rv
|
43
|
-
end
|
28
|
+
# Identify version
|
29
|
+
rv[:version] = $1 if agent =~ /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/
|
30
|
+
rv[:version_number] = rv[:version].to_f
|
44
31
|
|
45
|
-
|
46
|
-
|
47
|
-
|
32
|
+
# Identify platform
|
33
|
+
if agent =~ /linux/ then
|
34
|
+
rv[:platform] = :linux
|
35
|
+
elsif agent =~ /macintosh|mac os x/ then
|
36
|
+
rv[:platform] = :mac
|
37
|
+
elsif agent =~ /windows|win32|win64/ then
|
38
|
+
rv[:platform] = :windows
|
39
|
+
end
|
40
|
+
end
|
48
41
|
|
49
|
-
|
50
|
-
|
51
|
-
rv << "platform-#{@browser[:platform].to_s}"
|
42
|
+
@browser = rv
|
43
|
+
end
|
52
44
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
@browser[:version].split(/\./).each do |v|
|
57
|
-
i += 1
|
58
|
-
version += "#{i > 0 ? "_" : ""}#{v}"
|
59
|
-
rv << version
|
60
|
-
end
|
45
|
+
def browser_classes
|
46
|
+
self.browser_detect if !@browser
|
47
|
+
rv = []
|
61
48
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
49
|
+
# Add name and platform
|
50
|
+
rv << @browser[:engine].to_s
|
51
|
+
rv << "platform-#{@browser[:platform].to_s}"
|
52
|
+
|
53
|
+
# Add versions
|
54
|
+
version = "version-"
|
55
|
+
i = -1
|
56
|
+
@browser[:version].split(/\./).each do |v|
|
57
|
+
i += 1
|
58
|
+
version += "#{i > 0 ? "_" : ""}#{v}"
|
59
|
+
rv << version
|
60
|
+
end
|
61
|
+
|
62
|
+
rv.join(" ")
|
63
|
+
end
|
64
|
+
|
65
|
+
def browser_is?(engine = nil, version = nil, platform = nil)
|
66
|
+
self.browser_detect if !@browser
|
67
|
+
|
68
|
+
rv = true
|
69
|
+
rv = rv && (engine == @browser[:engine]) if engine.present?
|
70
|
+
rv = rv && (version == @browser[:version_number]) if version.present?
|
71
|
+
rv = rv && (platform == @browser[:platform]) if platform.present?
|
72
|
+
rv
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
77
|
end
|
@@ -5,39 +5,39 @@
|
|
5
5
|
#
|
6
6
|
|
7
7
|
module Cowtech
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
8
|
+
module RubyOnRails
|
9
|
+
module Helpers
|
10
|
+
module FormatHelper
|
11
|
+
def format_field(field, default = nil)
|
12
|
+
if field.is_a?(Fixnum) then
|
13
|
+
field
|
14
|
+
elsif field.is_a?(Float) then
|
15
|
+
field.format_number
|
16
|
+
elsif field.blank? || field.strip.blank? then
|
17
|
+
(default ? default : "Not set")
|
18
|
+
else
|
19
|
+
field
|
20
|
+
end
|
21
|
+
end
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
def currency_class(currency, include_positive = true, include_zero = true)
|
24
|
+
color = ""
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
if currency > 0 then
|
27
|
+
color = "positive" if include_positive
|
28
|
+
elsif currency < 0 then
|
29
|
+
color = "negative"
|
30
|
+
else
|
31
|
+
color = "zero" if include_zero
|
32
|
+
end
|
33
33
|
|
34
|
-
|
35
|
-
|
34
|
+
"class=\"numeric #{color}\""
|
35
|
+
end
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
37
|
+
def text_class(val, additional = nil)
|
38
|
+
"class=\"text #{additional.blank? ? nil : additional} #{val.blank? ? "unset" : nil}\""
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
43
|
end
|
@@ -5,229 +5,229 @@
|
|
5
5
|
#
|
6
6
|
|
7
7
|
module Cowtech
|
8
|
-
|
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
|
-
|
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
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
8
|
+
module RubyOnRails
|
9
|
+
module Helpers
|
10
|
+
module MongoidCrudHelper
|
11
|
+
attr_accessor :mongo_class
|
12
|
+
attr_accessor :records
|
13
|
+
attr_accessor :mongo_sort_order
|
14
|
+
attr_accessor :mongo_bounds
|
15
|
+
attr_accessor :mongo_query
|
16
|
+
attr_accessor :mongo_records
|
17
|
+
attr_accessor :mongo_pager
|
18
|
+
|
19
|
+
def mongo_setup(args = {})
|
20
|
+
@mongo_class = args[:class] if args[:class]
|
21
|
+
@mongo_class = @mongo_class.constantize if @mongo_class.is_a?(String)
|
22
|
+
@mongo_records = []
|
23
|
+
@mongo_sort_order = [[:_id, :asc]]
|
24
|
+
@mongo_bounds = {:total => 0, :first => 1, :last => 0, :pages => 1, :page => 1, :per_page => 1}
|
25
|
+
@mongo_query = self.mongo_reset_query(:also_deleted => args[:also_deleted]) if @mongo_class
|
26
|
+
end
|
27
|
+
|
28
|
+
def mongo_has_data?(args = {})
|
29
|
+
@mongo_bounds[:total] > 0
|
30
|
+
end
|
31
|
+
|
32
|
+
def mongo_calculate_bounds(args = {})
|
33
|
+
if @mongo_records.present? then
|
34
|
+
@mongo_bounds[:total] = @mongo_records.count
|
35
|
+
@mongo_bounds[:per_page] = (args[:per_page].is_integer? ? args[:per_page] : @mongo_records.first.class.per_page).to_integer
|
36
|
+
@mongo_bounds[:pages] = (@mongo_bounds[:total].to_f / @mongo_bounds[:per_page]).ceil
|
37
|
+
|
38
|
+
if @mongo_bounds[:per_page] > 0 then
|
39
|
+
@mongo_bounds[:page] = self.mongo_get_page_param(:upperbound => @mongo_bounds[:pages])
|
40
|
+
base = ((@mongo_bounds[:page] - 1) * @mongo_bounds[:per_page])
|
41
|
+
@mongo_bounds[:first] = base + 1
|
42
|
+
@mongo_bounds[:last] = [base + @mongo_bounds[:per_page], @mongo_bounds[:total]].min
|
43
|
+
else
|
44
|
+
@mongo_bounds.merge!(:pages => 1, :page => 1, :first => 1, :last => @mongo_bounds[:total], :per_page => @mongo_bounds[:total])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
@mongo_bounds
|
49
|
+
end
|
50
|
+
|
51
|
+
def mongo_fetch_data(args = {})
|
52
|
+
@mongo_records = @mongo_query.order_by(@mongo_sort_order)
|
53
|
+
self.mongo_calculate_bounds(args.reverse_merge(:per_page => (args[:per_page] || @mongo_per_page || params[args[:parameter] || :count])))
|
54
|
+
@records = @mongo_records.skip(@mongo_bounds[:first] - 1).limit(@mongo_bounds[:per_page])
|
55
|
+
@mongo_pager = WillPaginate::Collection.new(@mongo_bounds[:page], @mongo_bounds[:per_page], @mongo_bounds[:total])
|
56
|
+
end
|
57
|
+
|
58
|
+
def mongo_reset_query(args = {})
|
59
|
+
klass = args[:class] || @mongo_class
|
60
|
+
klass ? (args[:also_deleted] ? klass.where : klass.not_deleted) : nil
|
61
|
+
end
|
62
|
+
|
63
|
+
def mongo_dump_query(args = {})
|
64
|
+
raise Exception.new("QUERY:\n#{@mongo_query.inspect}")
|
65
|
+
end
|
66
|
+
|
67
|
+
def mongo_add_query_conditions(args = {})
|
68
|
+
(args[:conditions] || []).ensure_array.each do |condition|
|
69
|
+
if condition.is_a?(Hash) then
|
70
|
+
condition.each_pair do |key, val|
|
71
|
+
if key == "$or" then
|
72
|
+
@mongo_query = @mongo_query.any_of(val) # TODO: This don't work as expected. See: https://github.com/mongoid/mongoid/issues/569
|
73
|
+
else
|
74
|
+
@mongo_query = @mongo_query.where({key => val})
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
@mongo_query = yield(@mongo_query) if block_given?
|
81
|
+
@mongo_query
|
82
|
+
end
|
83
|
+
|
84
|
+
def mongo_parse_search(search)
|
85
|
+
if search.present? then
|
86
|
+
# Operate on parenthesis. If unbalanced, no substitution is done
|
87
|
+
if search.gsub(/[^(]/mi, "").strip.length == search.gsub(/[^)]/mi, "").strip.length then
|
88
|
+
# Split token
|
89
|
+
search = search.split(/(\s(AND|OR)\s)|([\(\)])/).select{ |t| !t.empty? && t !~ /^(AND|OR)$/}
|
90
|
+
|
91
|
+
# Replace tokens
|
92
|
+
search = search.collect { |token|
|
93
|
+
case token
|
94
|
+
when /[\(\)]/ then # No replace
|
95
|
+
token
|
96
|
+
when /\sAND\s/ then
|
97
|
+
"(.+)"
|
98
|
+
when /\sOR\s/ then
|
99
|
+
"|"
|
100
|
+
when /^\^(.+)/ then
|
101
|
+
"(^(#{Regexp.escape($1)}))"
|
102
|
+
when /(.+)\$$/ then
|
103
|
+
"((#{Regexp.escape($1)})$)"
|
104
|
+
else
|
105
|
+
"(" + Regexp.escape(token) + ")"
|
106
|
+
end
|
107
|
+
}.join("")
|
108
|
+
else
|
109
|
+
search = Regexp.quote(search)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
search
|
114
|
+
end
|
115
|
+
|
116
|
+
def mongo_handle_search(args = {})
|
117
|
+
parameter = args[:parameter] || :search
|
118
|
+
|
119
|
+
# Get the query
|
120
|
+
search_query = args[:query] || params[parameter]
|
121
|
+
if search_query.present? then
|
122
|
+
expr = self.mongo_parse_search(search_query)
|
123
|
+
|
124
|
+
# Build the query
|
125
125
|
or_query = []
|
126
|
-
|
127
|
-
|
128
|
-
|
126
|
+
(args[:fields] || []).each do |field|
|
127
|
+
or_query << {field.to_sym => Regexp.new(expr, Regexp::EXTENDED | Regexp::MULTILINE | Regexp::IGNORECASE)}
|
128
|
+
end
|
129
129
|
|
130
|
-
|
131
|
-
|
132
|
-
|
130
|
+
# Now add external fields
|
131
|
+
(args[:external] || []).each do |external|
|
132
|
+
external_query = external[:class].not_deleted
|
133
133
|
eor_query = []
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
@mongo_query = @mongo_query.any_of(or_query)
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
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
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
134
|
+
(external[:fields] || []).each do |field|
|
135
|
+
eor_query << {field.to_sym => Regexp.new(expr, Regexp::EXTENDED | Regexp::MULTILINE | Regexp::IGNORECASE)}
|
136
|
+
end
|
137
|
+
|
138
|
+
ids = external_query.any_of(eor_query).only(:id).all.collect { |r| r.id }
|
139
|
+
or_query << {external[:foreign_key].in => ids} if ids.count > 0
|
140
|
+
end
|
141
|
+
|
142
|
+
@mongo_query = @mongo_query.any_of(or_query)
|
143
|
+
end
|
144
|
+
|
145
|
+
@mongo_query
|
146
|
+
end
|
147
|
+
|
148
|
+
def mongo_handle_sorting(args = {})
|
149
|
+
order = args[:order] || [:current, [:updated_at, :desc]]
|
150
|
+
|
151
|
+
# Get current request sort order and then replace it into the sort fields
|
152
|
+
current = self.mongo_get_sort_param(:default => args[:default])
|
153
|
+
current_index = order.index(:current)
|
154
|
+
order[current_index] = current if current_index
|
155
|
+
|
156
|
+
# Assign data
|
157
|
+
@mongo_sort_order = order
|
158
|
+
end
|
159
|
+
|
160
|
+
def mongo_form_header(args = {})
|
161
|
+
args[:record].try(:new_record?) ? "Create" : "Edit"
|
162
|
+
end
|
163
|
+
|
164
|
+
def mongo_form_submit_label(args = {})
|
165
|
+
args[:record].try(:new_record?) ? "Create" : "Edit"
|
166
|
+
end
|
167
|
+
|
168
|
+
def mongo_get_page_param(args = {})
|
169
|
+
page = [params[args[:parameter] || :page].to_integer, 1].max
|
170
|
+
page = [page, args[:upperbound]].min if args[:upperbound].to_integer > 0
|
171
|
+
page
|
172
|
+
end
|
173
|
+
|
174
|
+
def mongo_get_sort_param(args = {})
|
175
|
+
if /^(?<what>[a-z0-9_]+)-(?<how>asc|desc)$/i.match(params[args[:param] || :sort_by]) && (args[:valids] || []).include?($~["what"]) then
|
176
|
+
[$~["what"].to_sym, $~["how"].downcase.to_sym]
|
177
|
+
else
|
178
|
+
args[:default] || [:created_at, :desc]
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def mongo_delete(args = {})
|
183
|
+
record = (args[:class] || @mongo_class).safe_find(args[:id])
|
184
|
+
|
185
|
+
if record then
|
186
|
+
args[:only_check] ? record.deletable? : record.delete(args[:definitive])
|
187
|
+
else
|
188
|
+
false
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def mongo_exists?(args)
|
193
|
+
args[:class].not_deleted.where(args[:conditions]).count > 0
|
194
|
+
end
|
195
|
+
|
196
|
+
def mongo_is_available?(args = {})
|
197
|
+
rv = self.setup_json_response(:validator)
|
198
|
+
rv["success"] = true
|
199
|
+
rv["valid"] = (self.mongo_exists?(args) == (args[:must_exists] || false))
|
200
|
+
args[:internal] ? rv : self.custom_respond_with(rv.to_json)
|
201
|
+
end
|
202
|
+
|
203
|
+
def mongo_update_params_black_list(args = {})
|
204
|
+
["controller", "action", "id", "subdomain"] + (args[:additional] || [])
|
205
|
+
end
|
206
|
+
|
207
|
+
def mongo_update_params(args = {})
|
208
|
+
blacklist = self.mongo_update_params_black_list(args)
|
209
|
+
session["params-#{self.location_name}"] = (params.delete_if { |k,v| blacklist.include?(k) || params[k].is_a?(Tempfile) || params[k].blank?})
|
210
|
+
end
|
211
|
+
|
212
|
+
def mongo_end_write_action(args = {})
|
213
|
+
redirect_to self.mongo_end_write_action_url(args)
|
214
|
+
end
|
215
|
+
|
216
|
+
def mongo_end_write_action_url(args = {})
|
217
|
+
rp = {}
|
218
|
+
|
219
|
+
if !args[:absolute] then
|
220
|
+
rp = session["params-#{self.location_name(:index)}"] || {}
|
221
|
+
rp[:action] = :index
|
222
|
+
end
|
223
|
+
|
224
|
+
if args[:additional].is_a?(Hash) then
|
225
|
+
args[:additional].each { |k, v| rp[k] = v }
|
226
|
+
end
|
227
|
+
|
228
|
+
url_for(rp)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
233
|
end
|