2012-01-13 36 views
16

Tôi khá mới để Rails và bây giờ tôi tình cờ gặp một vấn đề mà tôi đã không thể giải quyết với một người bạn của tôi Google :)Đường ray - Cách xác thực trường chỉ khi một trường khác có giá trị nhất định?

Ở dạng của tôi, tôi có một Select với ba giá trị: của Apple, ChuốiCherry. Nếu tôi chọn Apple từ lựa chọn Tôi ẩn một Chọn khác và một trường Văn bản với một số Javascript, bởi vì khi chọn Apple, không cần phải điền vào hai trường khác nữa.

Vì vậy, bây giờ tôi gặp sự cố khi xác thực biểu mẫu của tôi khi được gửi. Tôi đã tìm thấy một số vấn đề tương tự, ví dụ trong trường hợp "Chỉ xác thực một trường nếu trường khác trống."

Vấn đề này đã được giải quyết như thế này:

validates_presence_of :mobile_number, :unless => :home_phone? 

Vì vậy, tôi đã chỉ cố gắng điều đầu tiên mà nảy ra trong tâm trí tôi:

validates_presence_of :state, :granted_at, :if => :type != 1 

Nhưng khi tôi chạy nó, tôi nhận được lỗi này :

undefined method `validate' for true:TrueClass 

Vì vậy, bây giờ tôi không tìm hiểu cách tôi có thể truy cập các giá trị từ đối tượng được tạo ... Cảm ơn bạn trước vì sự giúp đỡ của bạn và tôi hy vọng câu hỏi của tôi không rõ ràng vì nó có vẻ như :-)

Trả lời

27

Vì nó là mã thực thi bạn cần bọc nó trong một lambda hoặc đối tượng Proc như sau:

validates_presence_of :state, :granted_at, :if => lambda { |o| o.type != 1 } 

# alternatively: 
..., :if => lambda { self.type != 1 } 
..., :if => Proc.new { |o| o.type != 1 } 
..., :if ->(o) { o.type != 1 } 
+0

cảm ơn bạn cho phản ứng nhanh :) nhưng những gì chứa biến khối này "o"? đối tượng đang được xác thực? – TehQuila

+0

Vâng, chính xác. Ngoài ra hãy xem câu trả lời của @ Hauleth nơi bạn có thể tìm thấy các cách khác để giải quyết vấn đề của bạn. Tham khảo cuối cùng có thể được tìm thấy trong Tài liệu API Rails: http://ar.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html hy vọng điều đó sẽ hữu ích. Hơn nữa tôi đề nghị bạn google cho "ruby procs và blocks" để tìm hiểu về các khối xây dựng cơ bản (ruby) đằng sau này. Hy vọng rằng sẽ giúp. – Matt

21

Bạn có thể sử dụng if cờ và lambda:

validates_presence_of :state, :granted_at, :if => lambda {self.type != 1} 

Hoặc chỉ cần tạo phương pháp riêng:

validates_presence_of :state, :granted_at, :if => :valid_type? 

private 
def valid_type? 
    type != 1 
end 
1

mặc dù những cách đề cập ở trên là những thực tiễn tốt nhất nhưng bạn cũng có thể làm cho nó đơn giản như thế này:

validates_presence_of :state, :granted_at, :if => "type!=1" 
1

Dựa trên các câu trả lời trước đó, bạn cũng có thể sử dụng một ngắn hơn "mũi tên" cú pháp

validates :state, :granted_at, presence: true, if: ->(o) { o.type != 1 } 
Các vấn đề liên quan