对我来说,这似乎是控制器要解决的问题。该模型仍然有效,如果它以“Rails”方式接收其属性,则可以正常工作。我的解决方案涉及控制器修改params
散列,以便模型甚至不知道视图中的更改。这取决于ActiveRecord中可能被视为私有 API 的行为,所以……公平警告 :-)
假设你有这个模型:
# app/models/example.rb
class Example < ActiveRecord::Base
attr_accessible :started_at # this is a DateTime
end
调整您的视图以使用正常text_field_tag
的日期部分(将通过 bootstrap-datepicker 增强)和 Rails 的time_select
时间部分:
# app/views/examples/_form.html.erb
<%= form_for(@example) do |f| %>
<p>
<%= f.label :started_at %>
<%= text_field_tag :started_at, @example.started_at.try(:to_date) %>
<%= f.time_select :started_at, :ignore_date => true %>
</p>
<p><%= f.submit %></p>
<% end %>
请注意,我们正在使用此表单,try
因为该表单将为新的和持久的记录呈现。这避免了started_at
属性为时的问题nil
。
before_filter
然后在控制器中创建一个以在将params
哈希发送到模型之前对其进行修改:
class ExamplesController < ApplicationController
before_filter :fix_params, :only => [:create, :update]
# ...
private
def fix_params
date = Date.parse(params.delete(:started_at))
params[:example].merge!({
'started_at(1i)' => date.year.to_s,
'started_at(2i)' => date.month.to_s,
'started_at(3i)' => date.day.to_s
})
end
end
本质上,我们将其解析params[:started_at]
为日期并将其分配给params[:example]
. 然后当参数最终传递给模型时,ActiveRecord 会started_at
正确分配模型的属性。
您需要进行一些错误检查和验证,但这应该适合您。