Comprendre Ruby on Rails modèle ActiveRecord accesseurs
-
22-09-2019 - |
Question
Mon modèle, « DataFile », a un tas de domaines que je voudrais mettre à l'extérieur du modèle, par exemple.
file = DataFile.new file.owner = 123
Maintenant, pour autant que je sache, je dois placer un « attr_accessor champ » dans mon modèle, pour tous les domaines que je voudrais modifier de l'extérieur. Cependant, le code ci-dessus fonctionne très bien sans avoir de attr_accessors défini, définissant le champ propriétaire à 123. Pourquoi?
Je pensais obtenir une « méthode non défini » erreur ou quelque chose comme ça.
La solution
Parce que l'ORM Rails utilise le modèle ActiveRecord, deux méthodes sont créés automatiquement pour chaque colonne dans la base de données associée à ce tableau: columnname et columnname = . Cela se produit « automatiquement » à la suite de votre modèle héritant de la base de ActiveRecord. Ces méthodes sont définies en utilisant les installations de métaprogrammation de rubis et sont créés dynamiquement au moment de la création de la classe.
Pour plus d'informations à exactement ce qui se passe, je prendrais un coup d'oeil à la source Rails. Cependant, ce qui précède est probablement suffisant pour vous donner une compréhension de travail de ce qui se passe.
Autres conseils
Drew et Zepplock avaient raison, mais je vais juste ajouter une chose. Les accesseurs que Rails (en fait, ActiveRecord) crée pour les champs de base de données ne sont PAS Ruby accesseurs, et si vous utilisez script / console vous verrez que le propriétaire n'est pas une variable d'instance du fichier objet.
Il est probable que vous ne remarquez pas jusqu'à ce que vous vous aventurez loin des accesseurs standard et essayez de manipuler @owner dans une méthode dans le dossier. Si vous apprenez Ruby en même temps que vous apprenez Rails (qui est ce que je l'ai fait), il est probable que vous tomberez ce à un moment donné. Ceci est la raison pour laquelle vous devez écrire:
class MyClass < ActiveRecord::Base
def invalidate_owner
self.owner = owner << " no longer owns this"
save
end
end
au lieu de
class MyClass < ActiveRecord::Base
def invalidate_owner
self.owner << " no longer owns this"
save
end
end
Très probablement « propriétaire » fait partie de votre modèle de base de données. Les accesseurs pour les champs de base de données sont générées automatiquement pour vous.