2012-03-02 12 views
25

Necesito asegurarme de que cuando se crea un producto tiene al menos una categoría. Podría hacer esto con una clase de validación personalizada, pero esperaba que hubiera una forma más estándar de hacerlo.Valide que un objeto tenga uno o más objetos asociados

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. products + categories es una gran oportunidad para conocer 'has_and_belongs_to_many' http://api.rubyonrails.org/classes/ActiveRecor d/Associations/ClassMethods.html # method-i-has_and_belongs_to_many. No necesita un modelo de unión a menos que no desee almacenar atributos adicionales junto con la asociación. 2. Puede usar la respuesta principal de esta pregunta http://stackoverflow.com/questions/6429389/how-can-i-make-sure-my-has- many-will-have-a-size-of-at- menos-2 adivina qué tienes que cambiar :) – jibiel

Respuesta

49

Existe una validación que verificará la duración de su asociación. Prueba esto:

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

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

¿Cómo escribo una especificación para probar esto? – abhishek77in

3

En lugar de la solución de wpgreenway, sugeriría usar un método de gancho, como se before_save y utilizar una asociación 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 

Y en su opinión, el uso puede utilizar, por ejemplo options_from_collection_for_select

25

Asegura que tiene al menos una categoría:

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

    validates :categories, :presence => true 
end 

encuentro el mensaje de error utilizando :presence es más claro que el uso de length minimum 1 validación

Cuestiones relacionadas