2013-05-24 39 views
5

Trong mô hình của tôi, tôi có điều này:cách đúng của ngăn chặn dữ liệu trùng nhau Rails

validates :name, :presence => true, :uniqueness => true 

Trong điều khiển của tôi, tôi có:

... 
if @location.save 
    format.html { redirect_to @location, :notice => 'Location was successfully created.' } 
    format.json { render :json => @location, :status => :created } 
... 

mà tạo ra thành công một kỷ lục nếu có chưa được một ghi lại với tên này trong bảng. Tôi nghĩ rằng đó là thực hành tốt để kiểm tra trước khi chèn một bản ghi có thể trùng lặp thay vì dựa vào các ràng buộc DB?

Tôi đoán tôi nên thêm thứ gì đó vào bộ điều khiển để kiểm tra? Cách chính xác để làm điều này là gì?

Rất cám ơn.

Trả lời

6

Xác thực được thực hiện bởi Rails trước khi bản ghi sẽ chạm vào cơ sở dữ liệu. Nếu bản ghi không thực hiện được xác thực, bản ghi sẽ không lưu và .save sẽ trả lại false, điều này sẽ gây ra mệnh đề else của trình điều khiển của bạn để thực thi. Điều khoản đó thường hiển thị lại trang đã được gửi, với các lỗi được hiển thị để chúng có thể được sửa chữa.

Giả sử bộ điều khiển của bạn được xây dựng như thế, bạn không cần phải làm gì khác. Bạn nên, tự nhiên, hãy chắc chắn rằng bất kỳ ràng buộc cơ sở dữ liệu được nhân đôi trong xác nhận hợp lệ của bạn, nếu không một bản ghi có thể vượt qua xác nhận nhưng tạo ra một lỗi từ vi phạm một hạn chế khi nó được lưu.

5

Bạn không cần phải làm bất cứ điều gì trong bộ điều khiển.

The correct way to prevent duplicate records in Rails is used 
validation in model which you did correctly. 
2

Bạn có cách chính xác để xác thực tính duy nhất trong Rails và đó là thông qua xác thực. Bạn không cần phải kiểm tra điều này trong bộ điều khiển bởi vì đó là những gì xác nhận cho bạn.

Hãy nhớ rằng việc thêm xác thực tính duy nhất không đảm bảo rằng bạn sẽ có một bản ghi duy nhất trong db. Điều này được giải thích một cách độc đáo trong số validates_uniqueness_of documentation trong api.

6

Thêm chỉ mục duy nhất trong cơ sở dữ liệu của bạn. Bằng cách đó, nếu một cái gì đó trượt qua xác nhận mô hình (hiếm, nhưng về mặt kỹ thuật có thể), truy vấn để lưu vào cơ sở dữ liệu sẽ thất bại.

4

Xác thực của bạn là chính xác. Cũng giống như tất cả các câu trả lời khác ở trên, tuy nhiên giả sử bạn muốn xác thực nhiều trường, ví dụ giả sử bạn có danh sách mong muốn, cần có user_iditem_id, bạn cần mỗi mục chỉ được người dùng thêm một lần, đối với loại kịch bản này thêm kiểu này xác nhận với mô hình của bạn

Class class_name < ActiveRecord::Base 
    validates_uniqueness_of :item_id, scope: :user_id 
end 
+0

bạn có thể sử dụng 'xác nhận: item_id, độc đáo: {scope:: user_id} ' về http://www.rubydoc.info/github/bbatsov/rubocop/Rubocop/Cop/Rails/Xác nhận – Math

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