2009-12-29 8 views
0

J'ai modèles comme ceci:Comment définir un champ dans le modèle comme étant en lecture seule lorsqu'une condition est remplie?

class Person 
    has_many :phones 
    ... 
end 

class Phone 
    belongs_to :person 
end 

Je veux interdire de changer les téléphones associés à une personne quand une condition est remplie. Le champ Interdit est défini sur disabled sous forme html. Lorsque j'ai ajouté une validation personnalisée pour le vérifier, cela provoquait une erreur de sauvegarde même lorsque le téléphone ne change pas. Je pense qu'il est parce qu'un hachage avec des attributs est passé à

@person.update_attributes(params[:person]) 

et il y a des données avec le numéro de téléphone (parce que la forme comprend des champs pour le téléphone). Comment mettre à jour seulement les attributs qui ont changé? Ou comment créer une validation qui ignore enregistre quand un champ ne change pas? Ou peut-être que je fais quelque chose de mal?

Répondre

4

Vous pourriez être en mesure d'utiliser les

changed # => [] 
changed? # => true|false 
changes # => {} 

méthodes qui sont fournis.

La méthode changed renverra un tableau d'attributs modifiés que vous pourrez peut-être comparer à include?(...) pour créer la fonctionnalité que vous recherchez.

Peut-être quelque chose comme

validate :check_for_changes 

def check_for_changes 
    errors.add_to_base("Field is not changed") unless changed.include?("field") 
end 
0
def validate 
    errors.add :phone_number, "can't be updated" if phone_number_changed? 
end 

- ne savent pas si cela fonctionne avec les associations bien

Autre moyen serait de passer outre update_attributes, trouver des valeurs qui n'ont pas changé et les supprimer de hachage params et enfin appeler update_attributes d'origine.

0

Pourquoi utilisez-vous pas before_create, callbacks before_save dans le modèle pour limiter la création/mise à jour/enregistrer/supprimer ou pratiquement une telle opération. Je pense accrocher des observateurs pour décider si vous voulez restreindre le créer ou autoriser; serait une bonne approche. Voici un petit exemple.

class Person < ActiveRecord::Base 

    #These callbacks are run every time a save/create is done. 
    before_save :ensure_my_condition_is_met 
    before_create :some_other_condition_check 


    protected 
    def some_other_condition_check 
    #checks here 
    end 

    def ensure_my_condition_is_met 
    # checks here 
    end 
end 

Plus d'informations pour callbacks peuvent être obtenues ici: http://guides.rubyonrails.org/activerecord_validations_callbacks.html#callbacks-overview

it helps.

+0

Merci! Le problème avec les callbacks est qu'il ne montre pas d'erreurs même quand je les ajoute à error.add_to_base – klew