簡體   English   中英

DateTime對話拋出“無法復制Fixnum”

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM