207 votes

Quelle est la bonne manière de substituer une méthode d’accesseur Set avec Ruby on Rails ?

Je suis à l'aide de Ruby on Rails 3.2.2 et je voudrais savoir si ce qui suit est un "bon"/"correct"/"sûr" au moyen de surcharger une méthode de définition pour un attribut de classe.

attr_accessible :attribute_name

def attribute_name=(value)
  ... # Some custom operation.

  self[:attribute_name] = value
end

Le code ci-dessus semble fonctionner comme prévu. Cependant, je voudrais savoir si, en utilisant le code ci-dessus, dans le futur, je vais avoir des problèmes ou, au moins, quels sont les problèmes que devrais-je m'attendre"/"qui pourrait arriver" avec Ruby on Rails. Si ce n'est pas la bonne façon de remplacer une méthode de définition, quelle est la bonne façon?


Note: Si j'utilise le code

attr_accessible :attribute_name

def attribute_name=(value)
  ... # Some custom operation.

  self.attribute_name = value
end

J'obtiens l'erreur suivante:

SystemStackError (stack level too deep):
  actionpack (3.2.2) lib/action_dispatch/middleware/reloader.rb:70

328voto

rubyprince Points 7665

Si vous voulez remplacer les méthodes de définition pour les colonnes d'une table lors de l'accès au moyen de modèles, c'est la façon de le faire.

class Model < ActiveRecord::Base
  attr_accessible :attribute_name

  def attribute_name=(value)
    # custom actions
    ###
    write_attribute(:attribute_name, value)
    # this is same as self[:attribute_name] = value
  end

end

Voir par défaut de substitution accesseurs dans les Rails de la documentation.

Donc, votre première méthode est la bonne façon de remplacer la colonne de poseurs dans les Modèles de Ruby on Rails. Ces accesseurs sont déjà fournis par des Rails pour accéder aux colonnes de la table comme des attributs du modèle. C'est ce que nous appelons ActiveRecord ORM cartographie.

Aussi garder à l'esprit que l' attr_accessible à la partie supérieure du modèle n'a rien à voir avec les accesseurs. Il a un tout autre functionlity (voir à cette question)

Mais dans la pure Ruby, si vous avez défini des accesseurs de la classe et de vouloir remplacer le setter, vous avez à faire usage de la variable d'instance comme ceci:

class Person
  attr_accessor :name
end

class NewPerson < Person
  def name=(value)
    # do something
    @name = value
  end
end

Ce sera plus facile à comprendre une fois que vous savez ce qu' attr_accessor . Le code attr_accessor :name est équivalent à ces deux méthodes (getter et setter)

def name # getter
  @name
end

def name=(value) #  setter
  @name = value
end

Aussi votre deuxième méthode n'est pas parce qu'il va provoquer une boucle infinie que vous appelez la même méthode attribute_name= à l'intérieur de cette méthode.

51voto

Robert Kajic Points 2416

Utiliser le `` mot clé :

À l’inverse, pour remplacer le lecteur :

16voto

Taimoor Changaiz Points 892

En rails 4

disons que vous avez un attribut d' âge dans votre table

 def age=(dob)   
    now = Time.now.utc.to_date
    age = now.year - dob.year - ((now.month > dob.month || (now.month == dob.month && now.day >= dob.day)) ? 0 : 1)
    super(age) #must add this otherwise you need to add this thing and place the value which you want to save. 
  end
 

Remarque: Pour les nouveaux arrivants dans les rails 4, vous n'avez pas besoin de spécifier attr_accessible dans le modèle. Au lieu de cela, vous devez mettre en liste blanche vos attributs au niveau du contrôleur en utilisant la méthode d' autorisation .

3voto

Robin Daugherty Points 1111

J’ai trouvé que (au moins pour les collections de relation ActiveRecord) travaux de mires de ce qui suit :

(Cela attrape les 3 premières entrées non pas en double dans le tableau passé.)

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