2012-03-02 9 views
25

Ho bisogno di assicurarmi che quando un prodotto viene creato abbia almeno una categoria. Potrei farlo con una classe di convalida personalizzata, ma speravo che esistesse un modo più standard per farlo.Convalida che un oggetto ha uno o più oggetti associati

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. prodotti + categorie è una grande opportunità per incontrare 'has_and_belongs_to_many' http://api.rubyonrails.org/classes/ActiveRecor d/Associazioni/ClassMethods.html # metodo-i-has_and_belongs_to_many. Non è necessario un modello di join a meno che non si desideri memorizzare ulteriori attributi insieme all'associazione. 2. È possibile utilizzare la risposta superiore da questa domanda http://stackoverflow.com/questions/6429389/how-can-i-make-sure-my-has-many-will-have-a-size-of-at- almeno 2 indovina cosa devi cambiare :) – jibiel

risposta

49

C'è una convalida che controllerà la durata dell'associazione. Prova questo:

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

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

Come scrivo una specifica per testarla? – abhishek77in

3

Invece di soluzione wpgreenway, vorrei suggerire di utilizzare un metodo gancio come before_save e utilizzare un'associazione 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 

E secondo lei, l'uso può usare per esempio options_from_collection_for_select

25

Assicura ha almeno una categoria:

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

    validates :categories, :presence => true 
end 

trovo il messaggio di errore utilizzando :presence è più chiaro che usando length minimum 1 convalida

Problemi correlati