40 votes

Valider qu'un objet a un ou plusieurs objets associés

Je dois m'assurer que lorsqu'un produit est créé, il comporte au moins une catégorie. Je pouvais le faire avec une classe de validation personnalisée, mais j'espérais qu'il y avait une façon plus standard de le faire.

 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

67voto

wpgreenway Points 571

Il y a une validation qui vérifiera la durée de votre association. Essaye ça:

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

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

52voto

Adrian Points 466

Assure qu'il a au moins une catégorie :

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

  validates :categories, :presence => true
end

Je trouve que le message d'erreur en utilisant :presence est plus clair qu'en utilisant la validation length minimum 1

4voto

ftanguy Points 57

Au lieu de la solution de wpgreenway, je suggérerais d'utiliser une méthode de crochet comme before_save et d'utiliser une association 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

Et à votre avis, l'utilisation peut utiliser par exemple options_from_collection_for_select

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X