Différence entre attr_accessor et attr_accessible

Dans Rails, quelle est la différence entre attr_accessor et attr_accessible ? D’après ce que j’ai compris, l’utilisation de attr_accessor est utilisée pour créer des méthodes de Object.variable et de Object.variable = some_value pour cette variable, afin que nous puissions accéder à la variable comme Object.variable ou Object.variable = some_value .

Je lis que attr_accessible rend cette variable spécifique accessible au monde extérieur. Quelqu’un peut-il s’il vous plaît me dire quelle est la différence

attr_accessor est une méthode Ruby qui crée un getter et un setter. attr_accessible est une méthode Rails qui vous permet de transmettre des valeurs à une affectation de masse: new(attrs) ou update_atsortingbutes(attrs) .

Voici un devoir de masse:

 Order.new({ :type => 'Corn', :quantity => 6 }) 

Vous pouvez imaginer que la commande pourrait également avoir un code de réduction, disons :price_off . Si vous ne :price_off pas :price_off comme attr_accessible vous attr_accessible le code malveillant de faire ainsi:

 Order.new({ :type => 'Corn', :quantity => 6, :price_off => 30 }) 

Même si votre formulaire n’a pas de champ pour :price_off , s’il est dans votre modèle, il est disponible par défaut. Cela signifie qu’un POST fabriqué peut toujours le définir. Utiliser attr_accessible white répertorie les éléments pouvant être assignés en masse.

Beaucoup de gens sur ce sujet et sur google expliquent très bien que attr_accessible spécifie une liste blanche d’atsortingbuts qui peuvent être mis à jour en bloc ( tous les atsortingbuts d’un modèle d’object en même temps ) Ceci est principalement (et uniquement) pour protéger votre application de “piratage” exploit pirate.

Ceci est expliqué ici sur le document officiel Rails: Affectation de masse

attr_accessor est un code ruby ​​permettant de créer (rapidement) des méthodes setter et getter dans une classe. C’est tout.

Maintenant, ce qui manque comme explication, c’est que lorsque vous créez en quelque sorte un lien entre un modèle (Rails) avec une table de firebase database, vous n’avez JAMAIS JAMAIS jamais besoin d’ attr_accessor dans votre modèle pour créer des gabarits afin de pouvoir modifier les enregistrements de votre table.

En effet, votre modèle hérite de toutes les méthodes de la classe ActiveRecord::Base , qui définit déjà les accesseurs de base CRUD (Créer, Lire, Mettre à jour, Supprimer) pour vous. Ceci est expliqué sur le document officiel ici Rails Model et ici Accesseur de réécriture par défaut (défiler jusqu’au chapitre “Ecraser l’accesseur par défaut”)

Dites par exemple que: nous avons une table de firebase database appelée “users” qui contient trois colonnes “firstname”, “lastname” et “role”:

Instructions SQL:

 CREATE TABLE users ( firstname ssortingng, lastname ssortingng role ssortingng ); 

J’ai supposé que vous définissiez l’option config.active_record.whitelist_atsortingbutes = true dans votre config / environment / production.rb pour protéger votre application contre l’exploit d’affectation en masse. Ceci est expliqué ici: Affectation de masse

Votre modèle Rails fonctionnera parfaitement avec le modèle ci-dessous:

 class User < ActiveRecord::Base end 

Cependant, vous devrez mettre à jour chaque atsortingbut d'utilisateur séparément dans votre contrôleur pour que la vue de votre formulaire fonctionne:

 def update @user = User.find_by_id(params[:id]) @user.firstname = params[:user][:firstname] @user.lastname = params[:user][:lastname] if @user.save # Use of I18 internationalization t method for the flash message flash[:success] = t('activerecord.successful.messages.updated', :model => User.model_name.human) end respond_with(@user) end 

Maintenant, pour vous faciliter la vie, vous ne voulez pas créer un contrôleur compliqué pour votre modèle d'utilisateur. Vous utiliserez donc la méthode spéciale attr_accessible dans votre modèle de classe:

 class User < ActiveRecord::Base attr_accessible :firstname, :lastname end 

Vous pouvez donc utiliser la "route" (assignation de masse) pour mettre à jour:

 def update @user = User.find_by_id(params[:id]) if @user.update_atsortingbutes(params[:user]) # Use of I18 internationlization t method for the flash message flash[:success] = t('activerecord.successful.messages.updated', :model => User.model_name.human) end respond_with(@user) end 

Vous n'avez pas ajouté les atsortingbuts "role" à la liste attr_accessible car vous ne laissez pas vos utilisateurs définir eux-mêmes leur rôle (comme admin). Vous faites cela vous-même sur une autre vue d'administrateur spéciale.

Bien que votre vue utilisateur n’affiche pas de champ "rôle", un pirate peut facilement envoyer une requête HTTP POST incluant "role" dans le hash params. L'atsortingbut "role" manquant sur attr_accessible sert à protéger votre application contre cela.

Vous pouvez toujours modifier votre atsortingbut user.role comme ci-dessous, mais pas avec tous les atsortingbuts.

 @user.role = DEFAULT_ROLE 

Pourquoi diable utiliseriez-vous attr_accessor ?

Eh bien, ce serait dans le cas où votre formulaire utilisateur affiche un champ qui n'existe pas dans votre table d'utilisateurs en tant que colonne.

Par exemple, disons que votre vue utilisateur affiche un champ "s'il vous plaît-dire-le-admin-que-je-suis-ici". Vous ne voulez pas stocker ces informations dans votre table. Vous voulez juste que Rails vous envoie un e-mail vous avertissant qu'un utilisateur "fou" 😉 s'est abonné.

Pour pouvoir utiliser ces informations, vous devez les stocker temporairement quelque part. Quoi de plus simple que de le récupérer dans un atsortingbut user.peekaboo ?

Donc, vous ajoutez ce champ à votre modèle:

 class User < ActiveRecord::Base attr_accessible :firstname, :lastname attr_accessor :peekaboo end 

Ainsi, vous pourrez utiliser l’atsortingbut user.peekaboo quelque part dans votre contrôleur pour envoyer un courrier électronique ou faire ce que vous voulez.

ActiveRecord n'enregistre pas l'atsortingbut "peekaboo" dans votre table lorsque vous effectuez une user.save par l' user.save car elle ne voit aucune colonne correspondant à ce nom dans son modèle.

attr_accessor est une méthode Ruby qui vous donne des méthodes de attr_accessor à une variable d’instance du même nom. Donc c’est équivalent à

 class MyModel def my_variable @my_variable end def my_variable=(value) @my_variable = value end end 

attr_accessible est une méthode Rails qui détermine quelles variables peuvent être définies dans une affectation de masse.

Lorsque vous soumettez un formulaire, et que vous avez quelque chose comme MyModel.new params[:my_model] vous voulez avoir un peu plus de contrôle, de sorte que les gens ne puissent pas soumettre les choses que vous ne voulez pas.

Vous pourriez faire attr_accessible :email pour que, quand quelqu’un met à jour son compte, il puisse changer son adresse email. Mais vous ne feriez pas attr_accessible :email, :salary car une personne pourrait alors fixer son salaire via une soumission de formulaire. En d’autres termes, ils pourraient se frayer un chemin vers une augmentation.

Ce type d’information doit être traité explicitement. Il ne suffit pas de le retirer du formulaire. Quelqu’un pourrait entrer avec firebug et append l’élément dans le formulaire pour soumettre un champ de salaire. Ils pourraient utiliser le curl intégré pour soumettre un nouveau salaire à la méthode de mise à jour du contrôleur, ils pourraient créer un script qui soumet un message avec ces informations.

Ainsi, attr_accessor consiste à créer des méthodes pour stocker des variables, et attr_accessible concerne la sécurité des affectations de masse.

attr_accessor est un code ruby ​​et est utilisé lorsque vous n’avez pas de colonne dans votre firebase database, mais que vous souhaitez toujours afficher un champ dans vos formulaires. La seule façon d’autoriser cela est d’ attr_accessor :fieldname et vous pouvez utiliser ce champ dans votre vue ou votre modèle, si vous le souhaitez, mais surtout dans votre vue.

Considérons l’exemple suivant

 class Address attr_reader :street attr_writer :street def initialize @street = "" end end 

Ici, nous avons utilisé attr_reader ( atsortingbut lisible ) et attr_writer ( atsortingbut accessible en écriture ) pour accéder à l’objective. Mais nous pouvons obtenir la même fonctionnalité en utilisant attr_accessor . En résumé, attr_accessor permet d’accéder aux méthodes getter et setter.

Le code ainsi modifié est le suivant

 class Address attr_accessor :street def initialize @street = "" end end 

attr_accessible vous permet de répertorier toutes les colonnes que vous souhaitez autoriser l’affectation de masse. Le contraire de ceci est attr_protected ce qui signifie que ce champ Je ne veux PAS que quiconque soit autorisé à se attr_protected en masse. Il est plus que probable que ce soit un champ dans votre firebase database auquel vous ne voulez pas que quiconque parle. Comme un champ d’état ou similaire.

En deux mots:

attr_accessor est getter , méthode setter . alors attr_accessible est de dire que cet atsortingbut particulier est accessible ou non. c’est tout.


Je souhaite append que nous devrions utiliser le paramètre Strong au lieu de attr_accessible pour protéger de l’ attr_accessible de masse.

À votre santé!

Un aperçu rapide et concis des différences:

attr_accessor est un moyen facile de créer des accesseurs en lecture et en écriture dans votre classe. Il est utilisé lorsque vous n’avez pas de colonne dans votre firebase database, mais que vous souhaitez toujours afficher un champ dans vos formulaires. Ce champ est un “virtual atsortingbute” dans un modèle Rails.

atsortingbut virtuel – atsortingbut ne correspondant pas à une colonne de la firebase database.

attr_accessible est utilisé pour identifier les atsortingbuts accessibles par vos méthodes de contrôleur, ce qui rend une propriété disponible pour une atsortingbution en masse. Elle permet uniquement d’accéder aux atsortingbuts que vous spécifiez, en refusant le rest.