Article: Rails internal 675

Rails
alide.myopenid.com 32
Updated over 2 years ago
Hầu hết mọi người khi mới dùng Rails đều trầm trồ vì sự đơn giản và tiện lợi của nó. Nhóm phát triển Rails đã tạo ra nó như thế nào? Nếu xem qua mã nguồn của Rails, có lẽ bạn còn trầm trồ hơn!
Rails là framework MVC để viết web. Nhóm phát triển Rails cấu trúc nó theo mô hình module rất dễ mở rộng. Thật ra việc dễ mở rộng này khả thi là nhờ ngôn ngữ Ruby.

 

Rails gồm nhiều thành phần, M: ActiveRecord, VC: ActivePack, ActionMailer, ActionWebservice, ActiveSupport.

Có thể nói ActiveSupport là thành phần bí ẩn nhất vì tài liệu khá khiệm tốn khi giải thích về nó. Ví dụ chính nhờ ActiveSupport mà khi kết quả của 1.kilobyte là 1024.

Tính năng validation hoạt động thế nào?

ActiveRecord chia làm nhiều thành phần. Các database model chúng ta khai báo trong chương trình đều dẫn xuất từ class ActiveRecord::Base. Để thực hiện validation, ActiveRecord::Base include module Validations. Điều này có nghĩa bản thân ActiveRecord::Base không có tính năng validation (không có thì vẫn chạy được), nhưng để có tính năng này thì chỉ cần đơn giản include Validations. Thiết kế này cho phép người viết phần ActiveRecord::Base làm việc độc lập với người viết phần Validations.

Trong ActiveRecord::Base có phương thức save. Để thực hiện tính năng validation, phương thức này được chặn lại và xử lí thích hợp bởi Validations. Việc chặn lại này khả thi bởi Ruby có tính năng alias.

Cụ thể, trong validations.rb có đoạn sau:

     def self.included(base) # :nodoc:       base.extend ClassMethods       base.class_eval do         alias_method_chain :save, :validation         alias_method_chain :save!, :validation         alias_method_chain :update_attribute, :validation_skipping       end     end 

alias_method_chain là phương thức do ActiveSupport cung cấp. Dòng

         alias_method_chain :save, :validation 

tạo ra 2 phương thức mới là save_with_validation và save_without_validation, trong đó save_without_validation chính là phương thức gốc.

Cũng trong validations.rb:

     def save_with_validation(perform_validation = true)       if perform_validation && valid? || !perform_validation         save_without_validation       else         false       end     end      def valid?       errors.clear        run_validations(:validate)       validate        if new_record?         run_validations(:validate_on_create)         validate_on_create       else         run_validations(:validate_on_update)         validate_on_update       end        errors.empty?     end      def run_validations(validation_method)         validations = self.class.read_inheritable_attribute(validation_method.to_sym)         if validations.nil? then return end         validations.each do |validation|           if validation.is_a?(Symbol)             self.send(validation)           elsif validation.is_a?(String)             eval(validation, binding)           elsif validation_block?(validation)             validation.call(self)           elsif validation_class?(validation, validation_method)             validation.send(validation_method, self)           else             raise(               ActiveRecordError,               "Validations need to be either a symbol, string (to be eval'ed), proc/method, or " +               "class implementing a static validation method"              )           end         end       end 
Nội dung phương thức valid? cho thấy thứ tự validation như sau:
  1. Những khai báo sử dụng phương thức của class, như validates_length_of, validates_numericality_of, validates_presence_of…
  2. Những khai báo ghi trong phương thức validation
  3. Những khai báo khi trong phương thức validate_on_create hoặc validate_on_update

Ngoài ra, đối với attribute nào đó, giả sử xảy ra nhiều error, thì thứ tự của các message trong mảng trả về từ <object>.errors.on(<attribute_name>) sẽ ngược với thứ tự validation trên.

Chỉ cần tìm hiểu thêm chút ít (ví dụ về phương thức read_inheritable_attribute, nằm trong ActiveSupport) là ta đã rõ cách hoạt động của tính năng validation. Qua đó cũng có thể thấy nhóm phát triển Rails chỉ cần vài trăm dòng Ruby mà đã thực hiện xong tính năng này. Không biết nhóm phát triển Struts phải bù đầu (và cả chúng ta khi sử dụng nữa!) với bao nhiêu dòng Java nhỉ :P ?

1 2 3 

Editors
alide.myopenid.com 32
ngocdaothanh.myopenid.com 148

Comments

You must login to be able to comment

Uploaded files

No file uploaded yet

You must login to be able to upload

Nhà tài trợ:

Mọi người đều tự do viết bài, sửa bài của người khác, và bình luận ở trang web này. Bạn muốn chủ động tạo bài mới để chia sẻ kinh nghiệm với mọi người? Xin click link ở dưới.

Create new content