add support for structured types as input parameters to scaffolding,

fixes scaffolding for APIs like metaWeblog that require an input
struct (by dropping structs in nested <ul> lists).


git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1265 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
Leon Breedt 2005-05-01 05:07:37 +00:00
parent b921b5da15
commit a080b1a231
6 changed files with 61 additions and 35 deletions

View File

@ -1,5 +1,7 @@
*SVN*
* Add support for structured types as input parameters to scaffolding, this should let one test the blogging APIs using scaffolding as well
* Fix that generated WSDL was not using relative_url_root for base URI #1210 [Shugo Maeda]
* Use UTF-8 encoding by default for SOAP responses, but if an encoding is supplied by caller, use that for the response #1211 [Shugo Maeda, NAKAMURA Hiroshi]

View File

@ -217,9 +217,9 @@ module ActionWebService # :nodoc:
# String representation of this method
def to_s
fqn = ""
fqn << (@returns ? (friendly_param(@returns[0], false) + " ") : "void ")
fqn << (@returns ? (@returns[0].human_name(false) + " ") : "void ")
fqn << "#{@public_name}("
fqn << @expects.map{ |p| friendly_param(p) }.join(", ") if @expects
fqn << @expects.map{ |p| p.human_name }.join(", ") if @expects
fqn << ")"
fqn
end
@ -236,13 +236,6 @@ module ActionWebService # :nodoc:
end
end
end
def friendly_param(type, show_name=true)
name = type.name.to_s
type_type = type.array?? type.element_type.type.to_s : type.type.to_s
str = type.array?? (type_type + '[]') : type_type
show_name ? (str + " " + name) : str
end
end
end
end

View File

@ -1,5 +1,3 @@
require 'ostruct'
require 'uri'
require 'benchmark'
require 'pathname'
@ -70,7 +68,13 @@ module ActionWebService
@invocation_cgi = @request.respond_to?(:cgi) ? @request.cgi : nil
bm = Benchmark.measure do
@protocol.register_api(@scaffold_service.api)
params = @params['method_params'] ? @params['method_params'].dup : nil
post_params = @params['method_params'] ? @params['method_params'].dup : nil
params = []
if @scaffold_method.expects
@scaffold_method.expects.length.times do |i|
params << post_params[i.to_s]
end
end
params = @scaffold_method.cast_expects(params)
method_name = public_method_name(@scaffold_service.name, @scaffold_method.public_name)
@method_request_xml = @protocol.encode_request(method_name, params, @scaffold_method.expects)
@ -156,30 +160,49 @@ module ActionWebService
end
module Helpers # :nodoc:
def method_parameter_input_fields(method, type)
name = type.name.to_s
type_name = type.type
unless type_name.is_a?(Symbol)
raise "Parameter #{name}: Structured/array types not supported in scaffolding input fields yet"
def method_parameter_input_fields(method, type, field_name_base)
if type.array?
return content_tag('em', "Typed array input fields not supported yet (#{type.name})")
end
field_name = "method_params[]"
case type_name
when :int
text_field_tag field_name
when :string
text_field_tag field_name
when :bool
radio_button_tag field_name, "True"
radio_button_tag field_name, "False"
when :float
text_field_tag field_name
when :time
select_datetime Time.now, 'name' => field_name
when :date
select_date Date.today, 'name' => field_name
if type.structured?
parameters = ""
type.each_member do |member_name, member_type|
label = method_parameter_label(member_name, member_type)
nested_content = method_parameter_input_fields(
method,
member_type,
field_name_base + '[' + member_name.to_s + ']')
if member_type.custom?
parameters << content_tag('li', label)
parameters << content_tag('ul', nested_content)
else
parameters << content_tag('li', label + ' ' + nested_content)
end
end
content_tag('ul', parameters)
else
case type.type
when :int
text_field_tag field_name_base
when :string
text_field_tag field_name_base
when :bool
radio_button_tag field_name_base, "True"
radio_button_tag field_name_base, "False"
when :float
text_field_tag field_name_base
when :time
select_datetime Time.now, 'name' => field_name_base
when :date
select_date Date.today, 'name' => field_name_base
end
end
end
def method_parameter_label(name, type)
name.to_s.capitalize + ' (' + type.human_name(false) + ')'
end
def service_method_list(service)
action = @scaffold_action_name + '_method_params'
methods = service.api_methods_full.map do |desc, name|

View File

@ -150,6 +150,12 @@ module ActionWebService # :nodoc:
def structured?
false
end
def human_name(show_name=true)
type_type = array? ? element_type.type.to_s : self.type.to_s
str = array? ? (type_type + '[]') : type_type
show_name ? (str + " " + name.to_s) : str
end
end
class ArrayType < BaseType # :nodoc:

View File

@ -10,13 +10,15 @@
</p>
<% if @scaffold_method.expects %>
<% i = 0 %>
<strong>Method Parameters:</strong><br />
<% @scaffold_method.expects.each do |type| %>
<p>
<label for="method_params[]"><%= type.name.to_s.camelize %></label><br />
<%= method_parameter_input_fields(@scaffold_method, type) %>
<label for="method_params[<%= i %>]"><%= method_parameter_label(type.name, type) %> </label><br />
<%= method_parameter_input_fields(@scaffold_method, type, "method_params[#{i}]") %>
</p>
<% i += 1 %>
<% end %>
<% end %>

View File

@ -53,7 +53,7 @@ class ScaffoldedControllerTest < Test::Unit::TestCase
end
def test_scaffold_invoke_submit_hello
post :scaffold_invoke_submit, :service => 'scaffolded', :method => 'Hello', :method_params => ['5', 'hello world']
post :scaffold_invoke_submit, :service => 'scaffolded', :method => 'Hello', :method_params => {'0' => '5', '1' => 'hello world'}
assert_rendered_file 'result.rhtml'
assert_equal false, @controller.instance_eval{ @method_return_value }
end