2012-01-09 20 views
5

Tôi đã rà soát API và dành hai đêm nhìn chằm chằm vào mã này và không may trong khi tôi cảm thấy tôi gần với giải pháp, tôi không thể làm cho nó hoạt động được. Tôi có một mô hình đại diện cho sự thay đổi, trong đó các thuộc tính khác có một thời gian bắt đầu.Bắt ngoại lệ được tăng lên trong trình truy cập tùy chỉnh trước khi đạt được xác thực mô hình (và hiển thị cho người dùng gặp lỗi [])

create_table "shifts", :force => true do |t| 
    t.datetime "start" 

Người dùng tương tác với ngày này đơn giản như ngày được đặt ở nơi khác, vì vậy tôi đã thiết lập người truy cập ảo để nhận và đặt.

class Shift < ActiveRecord::Base 
    def start_time 
    start.strftime("%H:%M") 
    end 

    def start_time=(time) 
    date = start.midnight 
    self.start = add_string_time_to_date(date, time) 
    end 

    def add_string_time_to_date(date, string_time) 
    t = DateTime.strptime(string_time, "%H:%M") 
    DateTime.new(date.year, date.month, date.mday, t.hour, t.min) 
    end 
end 

Tất cả đều hoạt động tốt khi được điều khiển thông qua bộ điều khiển tiêu chuẩn với @shift.update_attributes(params[:shift]).

Tôi muốn xác thực định dạng thời gian đã nhập nhưng không đơn giản như sử dụng phương thức bên dưới là strptime() tăng một đối số ArgumentError trước khi xác thực đạt được.

validates :start_time, :format => { :with => /^([0-1][0-9]|[2][0-3]):([0-5][0-9])$|^/, 
    :message => "Invalid format." } 

tôi có thể làm việc tròn này bằng cách đặt một cuộc gọi có điều kiện trong start_time() như ví dụ dưới đây, nhưng điều đó không thực sự làm việc một cách thỏa đáng vì hai lý do.

def start_time=(time) 
    if time =~ /^([0-1][0-9]|[2][0-3]):([0-5][0-9])$|^/ 
    date = start.midnight 
    self.start = add_string_time_to_date(date, time) 
    else 
    errors.add :start, "format invalid." 
    nil 
    end 
end 

ActiveRecord đầu tiên dường như không biết rằng setter đã thất bại. Tôi suy ra điều này từ thực tế update_attributes() trong bộ điều khiển trả về như thể tất cả là tốt, mặc dù nó không được. Thứ hai, không có phản hồi nào được trả lại cho người dùng, do đó, lệnh gọi đến errors.add có thể nằm ngoài ngữ cảnh. Nó cũng có một chút xấu xí.

Chức năng mong muốn là xác thực tiêu chuẩn, vì vậy nếu nó không thành công, người dùng sẽ thấy lỗi trên biểu mẫu giống như bất kỳ lỗi xác thực nào khác. Vì vậy, trong ngắn hạn, làm thế nào để tôi đạt được chức năng này, và tôi đang tiếp cận điều này một cách đúng đắn?

Tôi có cần phải nêu một ngoại lệ cụ thể để thông báo cho ActiveRecord về các rắc rối hay không và nếu như vậy tốt nhất là nên làm như thế nào? Cách tốt nhất là giải cứu và sử dụng đèn flash?

Trả lời

2

Bạn nên chia nhỏ logic của các thuộc tính này.

  • Đầu tiên xác định attr_accessor cho start_time (ngay cả khi nó chỉ được lưu trong bộ nhớ).
  • Sau đó, khởi tạo giá trị tương ứng.
  • Cuối cùng chỉ đặt thuộc tính bắt đầu khi mô hình được lưu.

này sẽ như thế nào:

class Shift < ActiveRecord::Base 
    attr_accessor :start_time 

    after_initialize :default_values 
    before_save :set_start 

    def add_string_time_to_date(date, string_time) 
    t = DateTime.strptime(string_time, "%H:%M") 
    DateTime.new(date.year, date.month, date.mday, t.hour, t.min) 
    end 

    private 

    def default_values 
    self.start_time = start.strftime("%H:%M") if start_time.nil? && start.present? 
    end 

    def set_start 
    if self.start_time.present? 
     date = start.midnight 
     self.start = add_string_time_to_date(date, time) 
    end 
    end 

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