使用Rails隐藏旧数据库中的unix时间戳

时间:2010-02-10 23:20:12

标签: ruby-on-rails timestamp

我正在使用旧数据库编写Ruby on Rails应用程序。我遇到的问题是我在数据库中有一个unix时间戳列。我正在尝试这样做,以便我可以写一个像"2010-10-10"这样的字符串,并在我阅读时获得一个日期。

def birthdate
  bdate = self[:birthdate]

  if bdate == 0
    ''
  else
    if bdate =~ $CetConfig.regexp.date_format.regexp
      bdate
    else
      Date.parse(Time.at(bdate).to_s)
    end
  end
end

def birthdate=(bdate)
  self[:birthdate]= Time.parse(bdate.to_s).to_i
end

这些是我必须尝试执行此操作的访问器,但是当由于错误或其他原因将数据重新填充到表单中时,我最终会在文本字段中使用时间戳而不是日期字符串。

这是表格。 (element_block只是将元素和标签包装在dl的右侧标签中)

<% form_for @pc, :url => { :controller => 'core', :action => 'create'}  do |f| %>
  <%= f.error_messages  %>
  <dl>
    <%= element_block  f.label(:contract, 'Contract Year'), f.contract_year_select(:contract) %>
    <% f.fields_for :profile_program do |pp| %>
      <%= element_block pp.label(:program, 'Program'), pp.hsp_program_select(:program) %>
    <% end %>

    <%= element_block f.label(:passport_number, 'Passport Number'), f.text_field(:passport_number) %>
    <%= element_block f.label(:passport_country, "Country that issued the student's passport"), f.countries_select(:passport_country) %>
    <%= element_block f.label(:passport_expires, 'Passport Expiration Date'), f.text_field(:passport_expires, :class => 'datepicker') %>
    <%= element_block f.label(:last_name, 'Last Name (as on passport)'), f.text_field(:last_name) %>
    <%= element_block f.label(:first_name, 'First Name (as on passport)'), f.text_field(:first_name) %>
    <%= element_block f.label(:middle_name, 'Middle Name (as on passport)'), f.text_field(:middle_name) %>
    <%= element_block f.label(:other_names, 'Other Names'), f.text_field(:other_names) %>
    <%= element_block f.label(:residence_street_address, 'Street Address'), f.text_field(:residence_street_address) %>
    <%= element_block f.label(:residence_city, 'City'), f.text_field(:residence_city) %>
    <%= element_block f.label(:residence_province, 'Province'), f.text_field(:residence_province) %>
    <%= element_block f.label(:residence, 'Country'), f.countries_select(:residence) %>
    <%= element_block f.label(:residence_postal_code, 'Postal Code'), f.text_field(:residence_postal_code) %>
    <%= element_block f.label(:birthdate, 'Date of Birth'), f.text_field(:birthdate) %>
    <%= element_block f.label(:citizenship, 'Country of Citizenship'), f.countries_select(:citizenship) %>
    <%= element_block f.label(:birth_city, 'Birth City'), f.text_field(:birth_city) %>
    <%= element_block f.label(:nationality, 'Nationality'), f.countries_select(:nationality) %>
    <%= element_block f.label(:gender, 'Gender'), f.gender_select(:gender) %>
    <%= element_block f.label(:email, 'Email'), f.text_field(:email) %>
    <%= element_block f.label(:desires_esl, 'Does the student wish to participate in CLEP?'), f.bool_yes_no_select(:desires_esl) %>
    <%= element_block f.label(:may_pay_tuiton, 'Willing to pay tuition'), f.yes_no_select(:may_pay_tuition) %>
  </dl>
  <div class="submit"><%= submit_tag("Proceed to Step Two") %></div>

<% end %>

这是我的助手

module ApplicationHelper
  def element_block label, element, example = ''
    example = '<br>' + example unless example.empty?
    "<dt>#{label}</dt><dd>#{element}#{example}</dd>"
  end
end

更新我也尝试了以下相同的结果。

def birthdate
  Time.at(read_attribute(:birthdate)).to_date
end

def birthdate=(bdate)
  write_attribute(:birthdate, bdate.to_time.to_i)
end

我正在使用Rails 2.3.5

2 个答案:

答案 0 :(得分:0)

首先,当您从数据库中获取零值时,不应返回空字符串:

>> Time.at(0)
=> Thu Jan 01 01:00:00 +0100 1970

其次,您应该使用ActiveRecord提供的方法进行读/写:

def birthdate
  Time.at(read_attribute(:birthdate)).to_date
end

def birthdate=(date)
  write_attribute(:birthdate, date.to_time.to_i)
end

答案 1 :(得分:0)

我最终做的是在模型中创建一个假日字段,并使用after_validation过滤器在真实字段上转换它。 在模型中

after_validation :write_birthdate

def write_birthdate
  bd = self.birthday
  unless bd.nil?
    write_attribute(:birthdate, Time.parse(bd).to_i)
  end
end

...

def birthday
  bd = read_attribute :birthday
  if bd.nil?
    bd = read_attribute :birthdate
    return Date.parse(Time.at(bd).to_s).to_s unless bd.nil? or bd === 0
    return nil
  end
  return bd
end

def birthday=(bdate)
  write_attribute(:birthday, bdate)
end

alias :birthdate :birthday
alias :birthdate= :birthday=

这样我就把生日写为日期,但是生日也是时间戳。