對我來說,這似乎是爲控制器解決問題有所幫助。該模型仍然有效,並會正常工作如果它以「Rails」方式接收它的屬性,我的解決方案就是控制器修改params
散列,以便模型甚至不知道視圖中的變化,這取決於behavior in ActiveRecord,它可以被認爲是私有API,所以...公正的警告:-)
說你有這個模型:
# app/models/example.rb
class Example < ActiveRecord::Base
attr_accessible :started_at # this is a DateTime
end
調整您的視圖使用正常text_field_tag
的日期部分(將由自舉日期選擇器來增強)和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
屬性。
你會想做一些錯誤檢查和驗證,但這應該爲你工作。
「fix_params」的第一行應該有params [:example],否則它將爲零。 –
實際上並非如此。由於我使用'text_field_tag'而不是'f.text_field',所以文本字段的名稱是'started_at',而不是'example [started_at]'。所以它確實生活在'params'散列的頂層。 – Brandan
噢,我跳過了。儘管我已經用f.text_field這種方式實現了它,並且它運行良好。 –