[英]DateTime conversation throws 'can't dup Fixnum'
我在帶有jruby 1.7.9的Ruby on Rails 4.0上有一個表單。 我用Mongoid代替ActiveRecord。
當我使用DateTime對象和附件(多部分文件)提交表單時,會引發錯誤“無法復制Fixnum”。 該應用程序將DateTime對象作為Unix時間戳存儲在數據庫中。
如果我提交的表單沒有DateTime,則會成功保存附件。 如果我提交的表單中沒有附件,它將按預期方式保存DateTime。 當兩者都實現時,將引發錯誤。
我怎樣才能解決這個問題?
完整的錯誤消息是:
can't dup Fixnum
Extracted source (around line #222):
220 self.data[name] = DateTime.parse(value).to_time.to_i
221 when 'datetime'
222 self.data[name] = DateTime.parse(value).to_time.to_i
223 when 'time'
224 self.data[name] = DateTime.parse(value).to_time.to_i
225 when 'number'
Rails.root: /Users/mehmetdavut/Documents/
Application Trace | Framework Trace | Full Trace
app/models/content.rb:222:in `change_property_types'
app/models/content.rb:214:in `change_property_types'
app/controllers/contents_controller.rb:56:in `update'
Request
Parameters:
{"utf8"=>"✓",
"_method"=>"patch",
"authenticity_token"=>"viv0CO7QKSY8kklTiLAXpdGkqv2W7fiW3Zrf2ZnKjpc=",
"content"=>{"data"=>{"second_datetime"=>"2014-04-07 17:20:00"},
"url"=>"",
"language_id"=>"ffef8bca0000ffd4b4cee70e",
"device_id"=>"52eeb9964d65682809130000",
"template_id"=>"fff02c4d0000a37cc11eed8f",
"layout_id"=>"fff02c760000a37cc11eed90",
"access"=>{"requires_authentication"=>"0",
"requires_ssl"=>"0"},
"discoverability"=>{"title"=>"",
"description"=>"",
"keywords"=>"",
"sitemap_change_frequency"=>"",
"sitemap_priority"=>"",
"exclude_from_search"=>"0"},
"menu"=>{"alias"=>"",
"class"=>"",
"passive"=>"0",
"script"=>"",
"show_in_navigation"=>"0",
"show_in_sitemap"=>"0"},
"taxonomy"=>{"category_id"=>"",
"tags"=>""},
"published_at"=>"2014-03-14T12:01:24-08:00",
"unpublished_at"=>""},
"attachments"=>{"second_file"=>#<ActionDispatch::Http::UploadedFile:0x162cbfcf @original_filename="Screen Shot 2014-03-13 at 00.38.30.png",
@headers="Content-Disposition: form-data; name=\"attachments[second_file]\"; filename=\"Screen Shot 2014-03-13 at 00.38.30.png\"\r\nContent-Type: image/png\r\n",
@tempfile=#<Tempfile:/var/folders/cs/6xmggtv54nq8l2xw77mzhtcr0000gn/T/RackMultipart20140314-18002-csbpyn>,
@content_type="image/png">},
"commit"=>"Update Content",
"page_id"=>"fff02ce20000a37cc11eed96",
"id"=>"fff02ce20000a37cc11eed97"}
這是“ change_property_types”方法:
def change_property_types
self.data.each do |name, value|
property = self.page.document.properties.where(name: name).first
unless value.blank?
case property.type
when 'date'
self.data[name] = DateTime.parse(value).to_time.to_i
when 'datetime'
self.data[name] = DateTime.parse(value).to_time.to_i
when 'time'
self.data[name] = DateTime.parse(value).to_time.to_i
when 'number'
self.data[name] = value.to_i
when 'file'
# self.attachments << Attachment.create(file: value)
else
self.data[name] = value
end
end
end
end
發生此錯誤的原因是value是一個fixnum。 以下代碼的輸出是什么?
...
when 'datetime'
raise value.class.inspect
...
您的表格是什么樣的?
如果這樣做,會發生什么:
unless value.blank?
case property.type
when 'date'
self.data[name] = DateTime.parse(value.to_s).to_time.to_i
when 'datetime'
self.data[name] = DateTime.parse(value.to_s).to_time.to_i
when 'time'
self.data[name] = DateTime.parse(value.to_s).to_time.to_i
when 'number'
self.data[name] = value.to_i
when 'file'
# self.attachments << Attachment.create(file: value)
else
self.data[name] = value
end
end
您的代碼中有很多重復項。 這使得它非常密集並且很難跟蹤您的錯誤。 我可能會這樣重構。 注意:這是未經測試的代碼重構
# DRY up your code :)
def change_property_types
data.each do |name, value|
next if value.blank?
self.data[name] = if get_property_type =~ /file/i
set_attachments(value)
elsif value.present? && check_dateishness
DateTime.parse(value).to_time.to_i
else
value
end
end
end
private
def check_dateishness
%w(date datetime time).include?(get_property_type)
end
# handle the case where attachements may be nil.
def set_attachements(value)
if self.attachments.blank?
self.attachments = [Attachment.create(file: value)]
else
self.attachments << Attachment.create(file: value)
end
end
# You could probably memoize this... i.e. @some_var ||= ...
def get_property_type
page.document.properties.where(name: name).first.type
end
或者您可以進一步分解代碼。
# Or decompose it to better track down errors
...
def change_property_types
data.each do |name, value|
next if value.blank?
if property_type =~ /file/
# you need to handle the attachments.nil?
attachments << Attachment.create(file: value)
else
data[name] = parse_it(property).to_i
end
end
end
private
def property_type
@property ||= page.document.properties \
.where(name: name).first.type
end
# Really this case statement can be simplified
# as you could check the class of the object, i.e.
# value.is_a?(Date) or value.is_a?(Time) and since
# the only Ruby class that needs to_time is Date
# you simplify the code
def parse_it(value)
case value.type
when 'time' then time_parser(value)
when 'date' then date_parser(value)
when 'datetime' then datetime_parser(value)
else value
end
end
def date_parser(date)
return date.to_time if date.is_a?(Date)
Date.parse(date.to_s).to_time
end
# Time has a to_i function
def time_parser(time)
return time if time.is_a?(Time)
Time.parse(time.to_s)
end
# DateTime has a to_i function
def datetime_parser(datetime)
return datetime if datetime.is_a?(DateTime)
DateTime.parse(datetime.to_s)
end
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.