2012-03-02 31 views
25

Tôi cần đảm bảo rằng khi một sản phẩm được tạo, nó có ít nhất một loại. Tôi có thể làm điều này với một lớp xác nhận tùy chỉnh, nhưng tôi đã hy vọng có một cách tiêu chuẩn hơn để làm điều đó.Xác nhận rằng đối tượng có một hoặc nhiều đối tượng liên kết

class Product < ActiveRecord::Base 
    has_many :product_categories 
    has_many :categories, :through => :product_categories #must have at least 1 
end 

class Category < ActiveRecord::Base 
    has_many :product_categories 
    has_many :products, :through => :product_categories 
end 

class ProductCategory < ActiveRecord::Base 
    belongs_to :product 
    belongs_to :category 
end 
+0

1. sản phẩm + danh mục là cơ hội tuyệt vời để đáp ứng 'has_and_belongs_to_many' http://api.rubyonrails.org/classes/ActiveRecor d) Các liên kết/ClassMethods.html # method-i-has_and_belongs_to_many. Bạn không cần tham gia mô hình trừ khi bạn không muốn lưu trữ các thuộc tính bổ sung cùng với liên kết. 2. Bạn có thể sử dụng câu trả lời hàng đầu từ câu hỏi này http://stackoverflow.com/questions/6429389/how-can-i-make-sure-my-has-many-will-have-a-size-of-at- ít nhất-2 đoán những gì bạn phải thay đổi :) – jibiel

Trả lời

49

Có xác thực sẽ kiểm tra độ dài của liên kết của bạn. Hãy thử điều này:

class Product < ActiveRecord::Base 
    has_many :product_categories 
    has_many :categories, :through => :product_categories 

    validates :categories, :length => { :minimum => 1 } 
end 
+1

Làm thế nào để viết một spec để kiểm tra này? – abhishek77in

3

Thay vì giải pháp wpgreenway, tôi sẽ đề nghị sử dụng một phương pháp móc như before_save và sử dụng một hiệp hội has_and_belongs_to_many.

class Product < ActiveRecord::Base 
    has_and_belongs_to_many :categories 
    before_save :ensure_that_a_product_belongs_to_one_category 

    def ensure_that_a_product_belongs_to_one_category 
    if self.category_ids < 1 
     errors.add(:base, "A product must belongs to one category at least") 
     return false 
    else 
     return true 
    end 
    end 

class ProductsController < ApplicationController 
    def create 
    params[:category] ||= [] 
    @product.category_ids = params[:category] 
    ..... 
    end 
end 

Và theo quan điểm của bạn, sử dụng có thể sử dụng ví dụ options_from_collection_for_select

25

Đảm bảo nó có ít nhất một thể loại:

class Product < ActiveRecord::Base 
    has_many :product_categories 
    has_many :categories, :through => :product_categories 

    validates :categories, :presence => true 
end 

tôi thấy thông báo lỗi sử dụng :presence là rõ ràng hơn so với sử dụng length minimum 1 xác nhận

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