- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下 Controller 规范示例传入我的基于 的纯 API 应用程序Rails 4.2.0 和 Ruby 2.2.1
let!(:params) { { user_token: user_token } }
context "- and optional address and contact details params value are received as a nil values -" do
it "doesn't set the address and contact details and responds with 201 success", check: true do
params.merge!(
address_street: nil, address_other: nil, city: nil, state: nil,
zip_code: nil, phone: nil)
post :create, params
expect(response).to have_http_status(201)
saved_client_id = json_response["id"]
saved_client = Client.find_by(id: saved_client_id)
expect(saved_client.address_street).to be_nil
expect(saved_client.address_other).to be_nil
expect(saved_client.city).to be_nil
expect(saved_client.state).to be_nil
expect(saved_client.zip_code).to be_nil
expect(saved_client.phone).to be_nil
end
end
1) Api::V1::ClientsController POST #create when receives valid client details - and optional address and contact details params value are received as nil values - doesn't set the address and contact details and responds with 201 success
Failure/Error: expect(saved_client.address_street).to be_nil
expected: nil
got: ""
# ./spec/controllers/api/v1/clients_controller_spec.rb:352:in `block (5 levels) in <top (required)>'
# ./spec/rails_helper.rb:61:in `block (3 levels) in <top (required)>'
# /home/jignesh/.rvm/gems/ruby-2.2.3@myapp-on-rails-5/gems/database_cleaner-1.5.1/lib/database_cleaner/generic/base.rb:16:in `cleaning'
# /home/jignesh/.rvm/gems/ruby-2.2.3@myapp-on-rails-5/gems/database_cleaner-1.5.1/lib/database_cleaner/base.rb:92:in `cleaning'
# /home/jignesh/.rvm/gems/ruby-2.2.3@myapp-on-rails-5/gems/database_cleaner-1.5.1/lib/database_cleaner/configuration.rb:86:in `block (2 levels) in cleaning'
# /home/jignesh/.rvm/gems/ruby-2.2.3@myapp-on-rails-5/gems/database_cleaner-1.5.1/lib/database_cleaner/configuration.rb:87:in `call'
# /home/jignesh/.rvm/gems/ruby-2.2.3@myapp-on-rails-5/gems/database_cleaner-1.5.1/lib/database_cleaner/configuration.rb:87:in `cleaning'
# ./spec/rails_helper.rb:60:in `block (2 levels) in <top (required)>'
gem 'rails', git: 'https://github.com/rails/rails.git'
gem 'rack', :git => 'https://github.com/rack/rack.git'
gem 'arel', :git => 'https://github.com/rails/arel.git'
GIT
remote: git://github.com/capistrano/rbenv.git
revision: 6f1216cfe0a6b4ac23ca4eaf8acf012e8165d247
specs:
capistrano-rbenv (2.0.3)
capistrano (~> 3.1)
sshkit (~> 1.3)
GIT
remote: https://github.com/rack/rack.git
revision: c393176b0edf3e5d06cabbb6eb9d9c7a07b2afa7
specs:
rack (2.0.0.alpha)
json
GIT
remote: https://github.com/rails/arel.git
revision: 3c429c5d86e9e2201c2a35d934ca6a8911c18e69
specs:
arel (7.0.0.alpha)
GIT
remote: https://github.com/rails/rails.git
revision: 58df2f4b4abcce0b698c2540da215a565c24cbc9
specs:
actionmailer (5.0.0.alpha)
actionpack (= 5.0.0.alpha)
actionview (= 5.0.0.alpha)
activejob (= 5.0.0.alpha)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 1.0, >= 1.0.5)
actionpack (5.0.0.alpha)
actionview (= 5.0.0.alpha)
activesupport (= 5.0.0.alpha)
rack (~> 2.x)
rack-test (~> 0.6.3)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.0.0.alpha)
activesupport (= 5.0.0.alpha)
builder (~> 3.1)
erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
activejob (5.0.0.alpha)
activesupport (= 5.0.0.alpha)
globalid (>= 0.3.0)
activemodel (5.0.0.alpha)
activesupport (= 5.0.0.alpha)
builder (~> 3.1)
activerecord (5.0.0.alpha)
activemodel (= 5.0.0.alpha)
activesupport (= 5.0.0.alpha)
arel (= 7.0.0.alpha)
activesupport (5.0.0.alpha)
concurrent-ruby (~> 1.0)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
method_source
minitest (~> 5.1)
tzinfo (~> 1.1)
rails (5.0.0.alpha)
actionmailer (= 5.0.0.alpha)
actionpack (= 5.0.0.alpha)
actionview (= 5.0.0.alpha)
activejob (= 5.0.0.alpha)
activemodel (= 5.0.0.alpha)
activerecord (= 5.0.0.alpha)
activesupport (= 5.0.0.alpha)
bundler (>= 1.3.0, < 2.0)
railties (= 5.0.0.alpha)
sprockets-rails (>= 2.0.0)
railties (5.0.0.alpha)
actionpack (= 5.0.0.alpha)
activesupport (= 5.0.0.alpha)
method_source
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
...
....
最佳答案
我找到了上述行为的根本原因:在 Rails 5 中,它是由默认 CONTENT_TYPE
引起的。 header 设置为 'application/x-www-form-urlencoded'
通过 ActionController::TestRequest #assign_parameters 方法,但在 Rails 4.2.0 中并非如此。
下面给出了我如何得出结论的详细调查结果:
在规范示例中传递的参数的上下文中(显示在我的问题帖子中),执行流程为 导轨 5 (及其机架版本)和 导轨 4.2.0 (及其机架版本)的详细方式如下:
导轨 5
actionpack/lib/action_dispatch/http_request.rb#form_data?返回真
actionpack/lib/action_dispatch/http_request.rb#POST 方法如下所示:
# Override Rack's POST method to support indifferent access
def POST
fetch_header("action_dispatch.request.request_parameters") do
pr = parse_formatted_parameters(params_parsers) do |params|
super || {}
end
self.request_parameters = Request::Utils.normalize_encode_params(pr)
end
rescue ParamsParser::ParseError # one of the parse strategies blew up
self.request_parameters = Request::Utils.normalize_encode_params(super || {})
raise
rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
raise ActionController::BadRequest.new("Invalid request parameters: #{e.message}")
end
alias :request_parameters :POST
fetch_header("action_dispatch.request.request_parameters")
时运行调用
super
的默认值 block 这使得调用转到 Rack 的 Request (/rack-c393176b0edf/lib/rack/request.rb) POST 方法。我在下面展示了这个方法的代码,我放了一些调试语句:
# Returns the data received in the request body.
#
# This method support both application/x-www-form-urlencoded and
# multipart/form-data.
def POST
puts ">>>>>>>>>>> DEBUG 2"
if get_header(RACK_INPUT).nil?
puts ">>>>>>>>>>> DEBUG 2.1"
raise "Missing rack.input"
elsif get_header(RACK_REQUEST_FORM_INPUT) == get_header(RACK_INPUT)
puts ">>>>>>>>>>> DEBUG 2.2"
get_header(RACK_REQUEST_FORM_HASH)
elsif form_data? || parseable_data?
puts ">>>>>>>>>>> DEBUG 2.3"
unless set_header(RACK_REQUEST_FORM_HASH, parse_multipart)
form_vars = get_header(RACK_INPUT).read
# Fix for Safari Ajax postings that always append \0
# form_vars.sub!(/\0\z/, '') # performance replacement:
form_vars.slice!(-1) if form_vars[-1] == ?\0
set_header RACK_REQUEST_FORM_VARS, form_vars
set_header RACK_REQUEST_FORM_HASH, parse_query(form_vars, '&')
get_header(RACK_INPUT).rewind
end
set_header RACK_REQUEST_FORM_INPUT, get_header(RACK_INPUT)
get_header RACK_REQUEST_FORM_HASH
else
puts ">>>>>>>>>>> DEBUG 2.4"
{}
end
>>>>>>>>>>> get_header RACK_REQUEST_FORM_HASH: {"address_other"=>"", "address_street"=>"", "city"=>"", "client_residence_type_id"=>"", "name"=>"Test Client 1", "phone"=>"", "provider_id"=>"64", "state"=>"", "zip_code"=>""}
parse_query(form_vars, '&')
将 nil 值转换为空字符串的方法。
# Override Rack's POST method to support indifferent access
def POST
@env["action_dispatch.request.request_parameters"] ||= Utils.deep_munge(normalize_encode_params(super || {}))
rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
raise ActionController::BadRequest.new(:request, e)
end
alias :request_parameters :POST
super
这使得调用转到 Rack 的 Request (rack-1.6.4/lib/rack/request.rb) POST 方法。我在下面展示了这个方法的代码,我放了一些调试语句:
def POST
puts ">>>>>>>>>>> DEBUG 2"
if @env["rack.input"].nil?
puts ">>>>>>>>>>> DEBUG 2.1"
raise "Missing rack.input"
elsif @env["rack.request.form_input"].equal? @env["rack.input"]
puts ">>>>>>>>>>> DEBUG 2.2"
@env["rack.request.form_hash"]
elsif form_data? || parseable_data?
puts ">>>>>>>>>>> DEBUG 2.3"
unless @env["rack.request.form_hash"] = parse_multipart(env)
form_vars = @env["rack.input"].read
# Fix for Safari Ajax postings that always append \0
# form_vars.sub!(/\0\z/, '') # performance replacement:
form_vars.slice!(-1) if form_vars[-1] == ?\0
@env["rack.request.form_vars"] = form_vars
@env["rack.request.form_hash"] = parse_query({ :query => form_vars, :separator => '&' })
@env["rack.input"].rewind
end
@env["rack.request.form_input"] = @env["rack.input"]
@env["rack.request.form_hash"]
else
puts ">>>>>>>>>>> DEBUG 2.4"
{}
end
end
content_mime_type
form_data?
内部使用已设置,因此规范示例提交的参数被解析为表单参数。
content_mime_type
未找到集content_mime_type
方法在
ActionDispatch::Http::MimeNegotiation
中定义模块
def content_mime_type
@env["action_dispatch.request.content_type"] ||= begin
if @env['CONTENT_TYPE'] =~ /^([^,\;]*)/
Mime::Type.lookup($1.strip.downcase)
else
nil
end
end
end
content_mime_type
方法在
ActionDispatch::Http::MimeNegotiation
中定义模块
def content_mime_type
fetch_header("action_dispatch.request.content_type") do |k|
v = if get_header('CONTENT_TYPE') =~ /^([^,\;]*)/
Mime::Type.lookup($1.strip.downcase)
else
nil
end
set_header k, v
end
end
if get_header('CONTENT_TYPE') =~ /^([^,\;]*)/
被评估为真,因此
Mime::Type.lookup($1.strip.downcase)
被退回
CONTENT_TYPE
没有被设置
def assign_parameters(routes, controller_path, action, parameters = {})
parameters = parameters.symbolize_keys.merge(:controller => controller_path, :action => action)
extra_keys = routes.extra_keys(parameters)
non_path_parameters = get? ? query_parameters : request_parameters
parameters.each do |key, value|
if value.is_a?(Array) && (value.frozen? || value.any?(&:frozen?))
value = value.map{ |v| v.duplicable? ? v.dup : v }
elsif value.is_a?(Hash) && (value.frozen? || value.any?{ |k,v| v.frozen? })
value = Hash[value.map{ |k,v| [k, v.duplicable? ? v.dup : v] }]
elsif value.frozen? && value.duplicable?
value = value.dup
end
if extra_keys.include?(key)
non_path_parameters[key] = value
else
if value.is_a?(Array)
value = value.map(&:to_param)
else
value = value.to_param
end
path_parameters[key] = value
end
end
# Clear the combined params hash in case it was already referenced.
@env.delete("action_dispatch.request.parameters")
# Clear the filter cache variables so they're not stale
@filtered_parameters = @filtered_env = @filtered_path = nil
params = self.request_parameters.dup
%w(controller action only_path).each do |k|
params.delete(k)
params.delete(k.to_sym)
end
data = params.to_query
@env['CONTENT_LENGTH'] = data.length.to_s
@env['rack.input'] = StringIO.new(data)
end
def assign_parameters(routes, controller_path, action, parameters, generated_path, query_string_keys)
non_path_parameters = {}
path_parameters = {}
parameters.each do |key, value|
if query_string_keys.include?(key)
non_path_parameters[key] = value
else
if value.is_a?(Array)
value = value.map(&:to_param)
else
value = value.to_param
end
path_parameters[key] = value
end
end
if get?
if self.query_string.blank?
self.query_string = non_path_parameters.to_query
end
else
if ENCODER.should_multipart?(non_path_parameters)
self.content_type = ENCODER.content_type
data = ENCODER.build_multipart non_path_parameters
else
fetch_header('CONTENT_TYPE') do |k|
set_header k, 'application/x-www-form-urlencoded'
end
case content_mime_type.to_sym
when nil
raise "Unknown Content-Type: #{content_type}"
when :json
data = ActiveSupport::JSON.encode(non_path_parameters)
when :xml
data = non_path_parameters.to_xml
when :url_encoded_form
data = non_path_parameters.to_query
else
@custom_param_parsers[content_mime_type] = ->(_) { non_path_parameters }
data = non_path_parameters.to_query
end
end
set_header 'CONTENT_LENGTH', data.length.to_s
set_header 'rack.input', StringIO.new(data)
end
fetch_header("PATH_INFO") do |k|
set_header k, generated_path
end
path_parameters[:controller] = controller_path
path_parameters[:action] = action
self.path_parameters = path_parameters
end
fetch_header('CONTENT_TYPE') do |k|
set_header k, 'application/x-www-form-urlencoded'
end
关于params - Rails 5 - Controller 规范示例 - 将参数设置为 nil 值将其值设置为空白字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33872958/
我经常看到这个,但我一直不明白。为什么这么多函数在函数定义中有这些嵌套的括号和奇怪的逗号? 有点像 function name(param, param param) 对我来说有意义,或者 funct
为什么参数输入有两种不同的格式?除了个人品味之外,还有其他好处吗? 例如,我正在使用它,因为那是我第一次阅读有关Powershell的文档时所看到的 function MyAwesomeFunctio
当我转到角色 Controller 时,显示操作,所有正常的 params[:id] 都是根据 REST 应该如何。 在显示 View 中,我渲染了部分。在该部分中,我有一个指向 vote_socio
我正在尝试在我的 Express 应用程序中使用 Sequelize 获取数据,并使用 MSSQL 获取数据库。这是我的代码: getInstitution: function (req, res)
从 ASP.NET 中的代码隐藏访问表单或查询字符串值时,使用的优缺点是什么,例如: // short way string p = Request["param"]; 代替: // long way
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: What is it called when you use object… as a parameter? 我在
在代码示例中,我看到了以下代码: SomeClass.Columns(columns => { columns.Add() .Text("Product")
我是 PySpark 的初学者。我在 PySpark 中使用 FPgrowth 计算关联。我按照以下步骤操作。 数据示例 from pyspark.sql.session import SparkSe
我想记录一个类,我在 PyCharm 中看到当自动添加文档字符串时它会添加 :param param_name1: :param param_name2: 不过,我看到有人用 @param param
我正在为一个网站设计 Android 客户端。所以我必须实现很多不同的网络操作。例如用户授权或在服务器上搜索。为此,我必须向 REST Web 服务器发送带有一些参数和 URL 的 JSON 请求。因
我对 Jersey 和 Grizzly 有疑问。这个问题可能非常基本,但我正在努力解决它。我的想法是,我正在创建一个需要存储书籍的练习应用程序。一切似乎都很好,但并没有按预期进行。这是源代码: @Pa
假设我有一个带有虚方法的接口(interface),但参数之一是: virtual void Delete(ParentClass *parentClass) = 0; 如果我稍后在子类中实现它 vo
需要一些 Python 语法方面的帮助 伪代码 if param is not None in params, param replace('xx', 'x') 我走到这一步了: param.repl
我刚开始使用 JSDocs,找不到这个问题的答案。 假设我想写这个简单的函数: function hasQ(array, item) {return array.includes(item);} 对于
我对doInBackground(Params...params)中的参数语法不熟悉 这种东西叫什么,我该如何使用它? 最佳答案 正如 devA 和 VVV 所说,这就是所谓的“可变参数”。实际上,以
我很难在两个 perl 模块之间做出选择——Params::Validate 和 Params::Check。 我正在编写一个应该易于分发的 Mojolicious 应用程序。 一般来说,我的意思是在
这个问题已经有答案了: What does [param: NotNull] mean in C#? (2 个回答) 已关闭 7 年前。 我发现了以下属性声明。 [param: Marsha
我正在阅读有关 $params 的 CakePHP 手册,并且想知道每个参数的适当用法是什么?我知道返回的数组略有不同(“url”实际上有一个名为“url”的数组键,它返回 Controller /操
我见过处理 *param1 和 ¶m2 的 C 函数调用 func1(*param1); func2(¶m2); 我知道 * 和 & 必须与指针相关。那么这两种不同的方式有
特别是,为什么对 *param 这样的参数的更改不会传播回函数的调用者,但对 **param 这样的参数的更改却会传播回来? 最佳答案 在这两种情况下,更改都会被传播,但这取决于调用函数。 请参阅下面
我是一名优秀的程序员,十分优秀!