Đối với tôi, điều này có vẻ như một vấn đề đối với bộ điều khiển để giải quyết. Mô hình này vẫn còn hiệu lực và sẽ làm việc tốt Giải pháp của tôi liên quan đến bộ điều khiển sửa đổi mã băm params
để mô hình thậm chí không nhận thức được những thay đổi trong chế độ xem. Điều này phụ thuộc vào behavior in ActiveRecord có thể được coi là API riêng tư, vì vậy… cảnh báo công bằng :-)
Giả sử bạn có mô hình này:
# app/models/example.rb
class Example < ActiveRecord::Base
attr_accessible :started_at # this is a DateTime
end
Điều chỉnh tầm nhìn của bạn để sử dụng bình thường text_field_tag
cho phần ngày (mà sẽ được tăng cường bởi bootstrap-datepicker) và Rails của time_select
cho phần thời gian:
# 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 %>
Chú ý rằng chúng ta đang sử dụng try
từ biểu mẫu này sẽ được hiển thị cho các bản ghi mới và. Điều này tránh được các vấn đề khi thuộc tính started_at
là nil
.
Sau đó tạo một before_filter
trong bộ điều khiển để thay đổi params
băm trước khi nó được gửi đến các mô hình:
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
Về cơ bản, chúng tôi đang phân tích params[:started_at]
như một ngày và gán nó vào các phím đúng params[:example]
. Sau đó, khi các tham số cuối cùng được truyền cho mô hình, ActiveRecord sẽ gán thuộc tính started_at
của mô hình một cách chính xác.
Bạn sẽ muốn thực hiện một số kiểm tra và xác thực lỗi nhưng điều này sẽ phù hợp với bạn.
Dòng đầu tiên của "fix_params" phải có thông số [: example], nếu không nó sẽ là 0. –
Đó không phải là trường hợp. Vì tôi đang sử dụng 'text_field_tag' thay cho' f.text_field', tên của trường text là 'begin_at', không phải' example [started_at] '. Vì vậy, nó sống ở cấp cao nhất của băm 'params'. – Brandan
Oh ok, tôi đã bỏ qua điều đó. Tôi đã thực hiện nó theo cách này với f.text_field mặc dù, và nó hoạt động tốt. –