Simple_form Datetime 字段 显示的时间不正确

simple_form 能够简化我们 rails 中创建表单的工作。 他还提供了高级功能让我们自定义表单的所有内容。

问题产生

当我们使用 simple_form 建立时间字段的时候,例如:

1
2
3
4
5
6
<%= simple_form_for(@user, html: { class: 'form-horizontal' }) do |f| %>
  <%= f.input :created_at %>
  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

默认的情况下 created_at 再表单中的时间是没有问题的。

但是当我们不满足于默认时间字段的多个 select html控件来选择时间, 而使用 DateTime Picker 更友好的方式设置时间的时候,我们需要这样做:

1
2
3
<%= simple_form_for(@user, html: { class: 'form-horizontal' }) do |f| %>
  <%= f.input :created_at, as: :string, input_html: {class: 'datetime'}%>
<% end %>

然后用 js 去生成时间日期选择。

这个时候会发现 created_at表单中的时间不是正确的。原因是Rails从数据库中读取时间字段后没有经过时区转换就被 simple_form 使用了

有关 Rails中如何正确使用时间 请点击查看。

解决方法

最简单的解决办法是:

1
2
3
<%= simple_form_for(@user, html: { class: 'form-horizontal' }) do |f| %>
  <%= f.input :created_at, as: :string, input_html: { class: 'datetime', value: f.object.created_at }%>
<% end %>

更好的解决办法:

如果程序中有很多这样的地方需要处理的话,每个去修改不是最明智的选择。 最好是利用 simple_form 重新定义 datetime 表单内容。

创建文件 app/inputs/date_time_input.rb

1
2
3
4
5
class DateTimeInput < SimpleForm::Inputs::Base
  def input()
    @builder.text_field(attribute_name, input_html_options.merge( { class: 'datetime', value: object.send( attribute_name ) } ))
  end
end

重新启动程序, 所有Datetime类型的字段都会自动生成这种时间选择表单, 并且时间是正确的了。

Comments