2012-06-21 29 views
10

Tôi mới dùng đường ray, vì vậy xin lỗi nếu trường này quá dễ.Sử dụng nhiều trường nhập cho một thuộc tính

Tôi có thuộc tính datetime trong mô hình của mình và tôi cố gắng đặt các giá trị trong đó với 3 phần tử biểu mẫu. Thứ nhất là ngày tháng và là biểu mẫu đầu vào (tôi sử dụng bootstrap-datepicker-rails và tôi muốn gắn bó với nó). Trong phần thứ hai, tôi muốn có một hộp chọn cho giờ và phần thứ ba là số phút.

Vì vậy, tôi thấy tôi có thể sử dụng DateHelpers datetime_select nhưng sau đó tôi không thể sử dụng bootstrap-datepicker nữa. Vì vậy, cách thích hợp để điền vào một thuộc tính (datetime) là gì bằng cách sử dụng nhiều hơn thì một phần tử đầu vào biểu mẫu. Tôi thấy rằng có cái gì đó như assign_multiparameter_attributes nhưng tài liệu không khá giúp :-(

Cảm ơn

Trả lời

10

Đố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 . Điều này tránh được các vấn đề khi thuộc tính started_atnil.

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.

+1

Dòng đầu tiên của "fix_params" phải có thông số [: example], nếu không nó sẽ là 0. –

+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

+1

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. –

Các vấn đề liên quan