【发布时间】:2012-03-20 21:47:56
【问题描述】:
我的头发快要掉光了,所以我一定是错过了一些基本的东西......
我有以下表格(简体):
<%= form_for(@public_call) do |f| %>
<div>Start: <%= f.date_select(:start_date,:start_year=>Time.now.year) -%></div>
<div>End: <%= f.date_select(:end_date,:start_year=>Time.now.year) -%></div>
<div>Deadline: <%= f.datetime_select(:submission_deadline,:start_year=>Time.now.year-1) -%></div>
<%- end -%>
表单发布到以下方法(简化):
def update
begin
@public_call = PublicCall.find(params[:id])
@public_call.update_attributes!(params[:public_call])
rescue
...
end
end
提交表单会导致 Rails 记录器报告以下内容(简化):
Parameters:
{"public_call"=>
{"start_date(1i)"=>"2012",
"start_date(2i)"=>"9",
"start_date(3i)"=>"30",
"end_date(1i)"=>"2012",
"end_date(2i)"=>"10",
"end_date(3i)"=>"3",
"submission_deadline(1i)"=>"2012",
"submission_deadline(2i)"=>"4",
"submission_deadline(3i)"=>"27",
"submission_deadline(4i)"=>"23",
"submission_deadline(5i)"=>"59"}
}
问题出在这里:Rails 似乎没有将三个字段的参数转换为数据库的日期和日期时间对象,就像它应该做的那样。 Rails 记录器报告的查询是:
UPDATE `public_calls` SET `start_date`=NULL, `end_date`=NULL, `submission_deadline`=NULL, `updated_at`='2012-03-20 20:47:15' WHERE...
知道什么给了?
顺便说一句,Rails 3.2.0 / Ruby 1.9.3。我在 public_calls 模型上的所有属性都不受保护。
谢谢!
编辑
还尝试将 :without_protection 选项与 update_attributes 一起使用!但这也不起作用。
编辑#2
我已经尝试调试 ActiveRecord 的 AttributeAssignment 模块中发生的事情,如下所示:
def assign_multiparameter_attributes(pairs)
Rails.logger.info('ASSIGN_MULTIPARAMETER_ATTRIBUTES: '+pairs.inspect)
execute_callstack_for_multiparameter_attributes(
extract_callstack_for_multiparameter_attributes(pairs)
)
end
def execute_callstack_for_multiparameter_attributes(callstack)
errors = []
Rails.logger.info('EXECUTE_CALLSTACK_FOR_MULTIPARAMETER_ATTRIBUTES: '+callstack.inspect)
callstack.each do |name, values_with_empty_parameters|
begin
send(name + "=", read_value_from_parameter(name, values_with_empty_parameters))
rescue => ex
errors << AttributeAssignmentError.new("error on assignment #{values_with_empty_parameters.values.inspect} to #{name}", ex, name)
end
end
unless errors.empty?
raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes"
end
end
def extract_callstack_for_multiparameter_attributes(pairs)
Rails.logger.info('EXTRACT_CALLSTACK_FOR_MULTIPARAMETER_ATTRIBUTES: '+pairs.inspect)
attributes = { }
pairs.each do |pair|
multiparameter_name, value = pair
attribute_name = multiparameter_name.split("(").first
attributes[attribute_name] = {} unless attributes.include?(attribute_name)
parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value)
attributes[attribute_name][find_parameter_position(multiparameter_name)] ||= parameter_value
end
Rails.logger.info('EXTRACT_CALLSTACK_FOR_MULTIPARAMETER_ATTRIBUTES: '+attributes.inspect)
attributes
end
这就是我得到的:
ASSIGN_MULTIPARAMETER_ATTRIBUTES: [["start_date(1i)", "2012"], ["start_date(2i)", "9"], ["start_date(3i)", "30"], ["end_date(1i)", "2012"], ["end_date(2i)", "10"], ["end_date(3i)", "3"], ["submission_deadline(1i)", "2012"], ["submission_deadline(2i)", "4"], ["submission_deadline(3i)", "27"], ["submission_deadline(4i)", "23"], ["submission_deadline(5i)", "59"]]
EXTRACT_CALLSTACK_FOR_MULTIPARAMETER_ATTRIBUTES: [["start_date(1i)", "2012"], ["start_date(2i)", "9"], ["start_date(3i)", "30"], ["end_date(1i)", "2012"], ["end_date(2i)", "10"], ["end_date(3i)", "3"], ["submission_deadline(1i)", "2012"], ["submission_deadline(2i)", "4"], ["submission_deadline(3i)", "27"], ["submission_deadline(4i)", "23"], ["submission_deadline(5i)", "59"]]
EXTRACT_CALLSTACK_FOR_MULTIPARAMETER_ATTRIBUTES: {"start_date"=>{1=>2012, 2=>9, 3=>30}, "end_date"=>{1=>2012, 2=>10, 3=>3}, "submission_deadline"=>{1=>2012, 2=>4, 3=>27, 4=>23, 5=>59}}
知道为什么没有调用 execute_callstack_for_multiparameter_attributes 方法吗?
【问题讨论】:
-
我也遇到了这个问题。你能弄明白吗?
标签: activerecord ruby-on-rails-3.2