2011-01-29 27 views
45

Người dùng có thể thêm thẻ vào một đoạn:Validate số mục has_many trong Ruby on Rails

class Snippet < ActiveRecord::Base 

    # Relationships 
    has_many :taggings 
    has_many :tags, :through => :taggings 
    belongs_to :closing_reason 

end 

Tôi muốn xác nhận số lượng thẻ: ít nhất 1, tối đa là 6. Làm thế nào tôi sắp làm cái này? Cảm ơn.

Trả lời

63

Bạn luôn có thể tạo custom validation.

Something như

validate :validate_tags 

    def validate_tags 
    errors.add(:tags, "too much") if tags.size > 5 
    end 
+12

tôi có lẽ sẽ sử dụng 'tags.count' sao cho DB làm việc và bạn không tải tất cả các thẻ chỉ dành riêng cho một xác nhận này. –

+7

@Beerlington: Trên thực tế có vẻ như Nikita là đúng, bạn không muốn nhấn cơ sở dữ liệu để xác thực, bạn muốn kiểm tra độ dài thực tế của "thẻ" của đối tượng. – tokland

+28

Nếu bạn sử dụng thẻ.size, nó thực hiện điều "đúng". xem http://blog.hasmanythrough.com/2008/2/27/count-length-size –

43

Một giải pháp tốt hơn đã được cung cấp bởi @SooDesuNe trên this SO post

validates :tags, length: { minimum: 1, maximum: 6 } 
+1

FWIW, thông báo lỗi mặc định cho điều này là "quá dài (tối đa là 100 ký tự)" – user605331

5

Tôi nghĩ rằng bạn có thể xác nhận với việc sử dụng .reject(&:marked_for_destruction?).length.

Làm thế nào về điều này?

class User < ActiveRecord::Base 
    has_many :groups do 
    def length 
     reject(&:marked_for_destruction?).length 
    end 
    end 
    accepts_nested_attributes_for :groups, allow_destroy: true 
    validates :groups, length: { maximum: 5 } 
end 

Hoặc điều này.

class User < ActiveRecord::Base 
    has_many :groups 
    accepts_nested_attributes_for :groups, allow_destroy: true 
    GROUPS_MAX_LENGTH = 5 
    validate legth_of_groups 

    def length_of_groups 
    groups_length = 0 
    if groups.present? 
     groups_length = groups.reject(&:marked_for_destruction?).length 
    end 
    errors.add(:groups, 'too many') if groups_length > GROUPS_MAX_LENGTH 
    end 
end 

Sau đó, bạn có thể chỉ huy.

@user.assign_attributes(params[:user]) 
@user.valid? 

Cảm ơn bạn đã đọc.

Tài liệu tham khảo:

http://homeonrails.com/2012/10/validating-nested-associations-in-rails/ http://qiita.com/asukiaaa/items/4797ce44c3ba7bd7a51f

+1

Tôi không có ý tưởng về khả năng chuyển khối thành phương thức liên kết. Đó là hiện tượng, cảm ơn bạn. –

+0

Hai năm sau: phương pháp 'length' trong khối thực sự không bao giờ được gọi. Một khối được truyền tới 'has_many' thực sự được gọi là phần mở rộng. Bạn có thể tạo "người tìm, người sáng tạo và các phương pháp kiểu nhà máy mới" mới với nó. https://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_many – haffla