J'utilise Rails 2.3.8 et accepte_nested_attributes_for.accepte_nested_attributes_for validation
J'ai un objet de catégorie simple qui utilise awesome_nested_set pour autoriser les catégories imbriquées.
Pour chaque catégorie je voudrais un champ unique appelé code. Ce serait unique pour la catégorie par niveau. Les catégories parentales auront tous des codes uniques et les sous-catégories seront uniques dans leur propre catégorie parentale.
EG:
code name
1 cat1
1 sub cat 1
2 cat2
1 sub cat 1
2 sub cat 2
3 cat3
1 sub1
Cela fonctionne sans le processus de validation, mais quand j'essaie d'utiliser quelque chose comme: validates_uniqueness_of: code,: scope =>: PARENT_ID
Cela ne fonctionnera pas parce que le parent n'a pas encore été enregistré.
Voici mon modèle:
class Category < ActiveRecord::Base
acts_as_nested_set
accepts_nested_attributes_for :children, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
default_scope :order => "lft"
validates_presence_of :code, :name, :is_child
validates_uniqueness_of :code, :scope => :parent_id
end
J'ai pensé à une autre façon de le faire et il est très proche de travailler, problème est que je ne peux pas vérifier l'unicité entre les catégories d'enfants.
Dans ce second exemple, j'ai inséré un champ caché dans la forme appelée 'is_child' pour indiquer si l'élément est une sous-catégorie ou non. Voici mon exemple de ce modèle:
class Category < ActiveRecord::Base
acts_as_nested_set
accepts_nested_attributes_for :children, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
default_scope :order => "lft"
validates_presence_of :code, :name, :is_child
#validates_uniqueness_of :code, :scope => :parent_id
validate :has_unique_code
attr_accessor :is_child
private
def has_unique_code
if self.is_child == "1"
# Check here if the code has already been taken this will only work for
# updating existing children.
else
# Check code relating to other parents
result = Category.find_by_code(self.code, :conditions => { :parent_id => nil})
if result.nil?
true
else
errors.add("code", "Duplicate found")
false
end
end
end
end
Ceci est très proche. S'il y avait un moyen de détecter les codes en double dans la syntaxe reject_if sous accept_nested_attributes_for alors je serais là. Tout cela semble trop compliqué et aimerait des suggestions pour le rendre plus facile. Nous aimerions continuer à ajouter des catégories et des sous-catégories dans le même formulaire, car cela accélère la saisie des données.
Mise à jour: Peut-être devrais-je utiliser build ou before_save.
Merci! J'ai essayé de valider un champ imbriqué en utilisant des valeurs de son objet parent dans le cadre de la validation. Il échouait sur de nouveaux objets car le parent n'était pas disponible. La: reverse_of declaration l'a fait fonctionner! –