2008-12-17 6 views
143

Un exemple de ce dont je parle:Remplacer les méthodes d'attributs ActiveRecord

class Person < ActiveRecord::Base 
    def name=(name) 
    super(name.capitalize) 
    end 
    def name 
    super().downcase # not sure why you'd do this; this is just an example 
    end 
end 

Cela semble fonctionner, mais je viens de lire la section sur le remplacement des méthodes d'attributs dans le ActiveRecord::Base docs, et il suggère d'utiliser la read_attribute et write_attribute des méthodes. Je pensais qu'il devait y avoir quelque chose de mal avec ce que je fais dans l'exemple ci-dessus; sinon, pourquoi béniraient-ils ces méthodes comme étant la «bonne façon» de remplacer les méthodes d'attributs? Ils forcent également un idiome beaucoup plus laid, donc il doit y avoir une bonne raison ...

Ma vraie question: Y at-il quelque chose de mal avec cet exemple?

Répondre

199

En écho aux commentaires de Gareth ... votre code ne fonctionnera pas tel qu'il a été écrit. Il devrait être reformulé ainsi:

def name=(name) 
    write_attribute(:name, name.capitalize) 
end 

def name 
    read_attribute(:name).downcase # No test for nil? 
end 
+0

Exactement ce dont j'avais besoin. Merci Aaron. – bong

+15

Ce n'est plus vrai. Soit super ou ça marche maintenant. Cependant, je n'ai pas testé la notation de hachage. – tehgeekmeister

+2

Dans les rails 3, la méthode de lecture spécifiée ici par Aaron fonctionne, mais l'auteur que l'affiche originale a spécifié (alimentant le nom à super) fonctionne bien, et IMHO est plus propre qu'écrire manuellement l'attribut comme Aaron suggère. – Batkins

88

Dans le prolongement de la réponse d'Aaron Longwell, vous pouvez également utiliser une « notation de hachage » aux attributs d'accès qui ont redéfinis accesseurs et mutateurs:

def name=(name) 
    self[:name] = name.capitalize 
end 

def name 
    self[:name].downcase 
end 
+0

La notation de hachage peut fonctionner, mais 'self.attribute' souffle la pile sur 3.2.16. – jrhorn424

+0

Ceci a l'avantage de supporter '|| =' par defaut: 'def name; self [: nom] || = 'anon'; end' –

-1

Je un plugin de rails qui fait fonctionner le surpassement d'attributs avec super comme vous pouvez vous y attendre. Vous pouvez le trouver sur github.

Pour installer:

./script/plugin install git://github.com/chriseppstein/has_overrides.git 

Pour utiliser:

class Post < ActiveRecord::Base 

    has_overrides 

    module Overrides 
    # put your getter and setter overrides in this module. 
    def title=(t) 
     super(t.titleize) 
    end 
    end 
end 

Une fois que vous avez fait que les choses fonctionnent:

$ ./script/console 
Loading development environment (Rails 2.3.2) 
>> post = Post.new(:title => "a simple title") 
=> #<Post id: nil, title: "A Simple Title", body: nil, created_at: nil, updated_at: nil> 
>> post.title = "another simple title" 
=> "another simple title" 
>> post.title 
=> "Another Simple Title" 
>> post.update_attributes(:title => "updated title") 
=> true 
>> post.title 
=> "Updated Title" 
>> post.update_attribute(:title, "singly updated title") 
=> true 
>> post.title 
=> "Singly Updated Title" 
+3

Ceci est déjà intégré dans les rails – ramn

Questions connexes