2010-03-02 20 views
37

Có thực tế tốt hơn (và tại sao) để xác thực các thuộc tính trong mô hình hoặc trong định nghĩa cơ sở dữ liệu?Ruby on Rails: Có tốt hơn để xác thực trong mô hình hoặc cơ sở dữ liệu không?

Đối (một tầm thường) ví dụ:

Trong mô hình sử dụng:

validates_presence_of :name 

so với trong cuộc di cư:

t.string :name, :null => false 

Một mặt, bao gồm nó trong cơ sở dữ liệu dường như nhiều hơn một đảm bảo chống lại bất kỳ loại dữ liệu xấu lẻn vào. Mặt khác, bao gồm nó trong mô hình làm cho mọi thứ minh bạch hơn và dễ hiểu hơn bằng cách nhóm nó trong mã với phần còn lại o f các xác nhận hợp lệ. Tôi cũng xem xét làm cả hai, nhưng điều này có vẻ như cả hai không DRY và ít bảo trì.

Trả lời

45

Tôi thực sự khuyên bạn nên làm điều đó ở cả hai nơi. Làm điều đó trong mô hình giúp bạn tiết kiệm một truy vấn cơ sở dữ liệu (có thể trên mạng) mà về cơ bản sẽ bị lỗi, và thực hiện nó trong cơ sở dữ liệu đảm bảo tính nhất quán của dữ liệu.

+1

Bạn đánh bại tôi đến 20 giây;) – Aurril

+4

Tôi đồng ý với việc xác thực ràng buộc ở cả hai nơi (tôi sử dụng PostgreSQL và plugin sexy_pg_constraints http://github.com/maxim/sexy_pg_constraints cho việc này) nhưng không hoàn toàn đúng xác thực các mô hình của bạn sẽ lưu truy vấn DB. Ví dụ, 'validates_uniqueness_of' phải thực hiện truy vấn DB. –

4

Thực hành tốt là thực hiện cả hai. Xác thực mô hình là thân thiện với người dùng trong khi xác thực cơ sở dữ liệu bổ sung một thành phần cuối cùng làm cho mã của bạn khó khăn hơn và tiết lộ các xác nhận bị thiếu trong logic ứng dụng của bạn.

2

Nó thay đổi. Tôi nghĩ rằng việc xác thực đơn giản, liên quan đến dữ liệu (như độ dài chuỗi, ràng buộc trường, v.v ...) nên được thực hiện trong cơ sở dữ liệu. Bất kỳ xác nhận nào tuân theo một số quy tắc kinh doanh nên được thực hiện trong mô hình.

0

Tùy thuộc vào thiết kế ứng dụng của bạn, Nếu bạn có ứng dụng cỡ nhỏ hoặc trung bình, bạn có thể thực hiện cả hai hoặc chỉ trong mô hình, Nhưng nếu bạn có một ứng dụng lớn có thể là dịch vụ của nó hoặc theo lớp thì xác nhận có nghĩa là bắt buộc/nullable, min/max chiều dài vv trong cơ sở dữ liệu và nghiêm ngặt hơn tức là patters hoặc quy tắc kinh doanh trong mô hình.

11

Và cũng

validates_presence_of :name 

không giống nhau để

t.string :name, :null => false 

Nếu bạn chỉ cần đặt KHÔNG cột NULL trong DB của bạn, bạn vẫn có thể chèn giá trị trống (""). Nếu bạn đang sử dụng mô hình validates_presence_of - bạn không thể.

+1

Tốt, cảm ơn. Tôi có bị mù hay không, thực sự không có validates_not_nil được đặt trước để đưa vào logic mô hình để phù hợp với logic cơ sở dữ liệu như mọi người đã đề xuất không? –

1

Tôi muốn giới thiệu dự án Migration Validators (https://rubygems.org/gems/mv-core) để xác định xác thực trên cấp độ db và sau đó quảng bá rõ ràng mô hình ActiveRecord.

Ví dụ:

trong di cư:

def change 
    create_table :posts do |t| 
    t.string :title, length: 1..30 
    end 
end 

trong mô hình của bạn:

class Post < ActiveRecord::Base 
    enforce_migration_validations 
end 

Như kết quả bạn sẽ có hai mức độ xác nhận dữ liệu. Việc đầu tiên sẽ được thực hiện trong db (như điều kiện trong kích hoạt của ràng buộc kiểm tra) và thứ hai là xác nhận ActiveModel trong mô hình của bạn.

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