2009-10-11 5 views
0

Je la situation suivanteUn seul enregistrement vrai, tous les autres faux, dans des rails

class RecordA 
    has_many :recordbs 
end 

class RecordB 
    belongs_to :recorda 
end 

a beaucoup recordbs l'enregistrement RecordA mais seulement un d'entre eux peut être un recordb actif. Je besoin de quelque chose comme myRecordA.active_recordb

Si j'ajoute une nouvelle colonne comme is_active à RecordB, j'ai le problème potentiel de mettre deux dossiers à is_active = true en même temps.

Quel motif de conception puis-je utiliser?

Merci!

+1

Il est préférable d'utiliser des noms de modèles REAL plutôt que "RecordA" et "RecordB", aide les gens à penser comment vous pensez, –

Répondre

1

Vous pouvez définir une méthode de classe sur RecordB pour cela:

class RecordB < ActiveRecord::Base 
    def self.active 
    first(:conditions => { :active => true } 
    end 
end 
5

Changeons votre exemple. Il y a une salle de lecture, avec beaucoup de gens et une seule personne peut être l'instructeur.

Il serait beaucoup plus facile d'avoir un attribut dans la salle de cours pour indiquer quelle personne est l'instructeur. De cette façon, vous n'avez pas besoin de changer plusieurs enregistrements de personnes afin d'échanger l'instructeur. Vous avez juste besoin de mettre à jour l'enregistrement LectureRoom.

+0

absolument d'accord. – Peter

1

J'utiliserais une portée nommée pour trouver le conférencier actif.

class Person 
    named_scope :currently_speaking, :conditions => {:active => true} 
end 

Je qualifierais que chargé de cours en Classroom:

class ClassRoom 
    def lecturer 
    people.currently_speaking.first 
    end 
end 

Le vrai problème est en vous assurant que lorsque vous activez quelqu'un d'autre, ils deviennent la seule personne active. Je pourrais le faire comme ceci:

class Person 
    belongs_to :class_room 

    before_save :ensure_one_lecturer 

    def activate! 
    self.active = true 
    save 
    end 

    def ensure_one_lecturer 
    if self.active && changed.has_key?(:active) 
     class_room.lecturer.update_attribute(:active, false) 
    end 
    end 

end 

Ce tout est fait dans moyen d'une transaction, il est seulement fait si vous avez modifié l'état actif, et devrait être testé assez facilement (je ne l'ai pas testé).

+0

En outre, je devrais ajouter, vous devrez peut-être utiliser un verrou sur la table des personnes en faisant ceci ou vous pourriez voir une condition de course en activant des personnes. –

Questions connexes