240 votes

Différence entre attr_accessor et attr_accessible

En RoR, quelle est la différence entre attr_accessor et attr_accessible. De ma compréhension, en utilisant attr_accessor est utilisé pour créer des accesseurs et des mutateurs pour cette variable, de sorte que nous pouvons accéder à la variable comme

`Object.variable`   or    `Object.variable = some_value`

J'ai lu que attr_accessible fait que d'une variable spécifique accessible au monde extérieur. Quelqu'un peut-il me dire quel est la différence

261voto

Paul Rubel Points 13132

attr_accessor est une méthode ruby qui fait un getter et un setter. attr_accessible est un Rails de la méthode qui permet de passer des valeurs à une masse d'affectation: new(attrs) ou update_attributes(attrs).

Voici une masse d'affectation:

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

Vous pouvez imaginer que l'ordre pourrait aussi y avoir un code de réduction, dire :price_off. Si vous n'avez pas de balise :price_off comme attr_accessible vous arrêtez de code malveillant d'être capable de faire comme suit:

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

Même si votre formulaire n'est pas un terrain pour :price_off, si c'est dans votre modèle, il est disponible par défaut. Cela signifie un POST artisanaux pourrait encore ensemble. À l'aide de attr_accessible les listes blanches de ces choses qui peuvent être de masse attribuée.

174voto

Douglas Points 1664

C'est une très bonne question. J'ai été aussi très confus avec tout cela, et j'ai enfin undersood le point.

Beaucoup de gens sur ce fil et sur google expliquent très bien que :

attr_accessible spécifie une liste d'attributs qui sont autorisés à être mis à jour en vrac (tous les attributs d'un objet de modèle d'ensemble en même temps) C'est surtout (et uniquement) pour protéger votre application à partir de "Masse assignement" pirate de l'exploiter. C'est expliqué ici sur le site officiel de Rails doc : Masse Assignement

attr_accessor est un code ruby (rapidement) créer setter et getter dans une Classe. C'est tout.

MAINTENANT, qu'est-ce que l'absence d'explication, c'est que lorsque vous créez quelque sorte un lien entre un (rails)modèle avec une table de base de données vous de ne JAMAIS, jamais, JAMAIS besoins attr_accessor dans votre modèle pour créer les setters et getters pour être en mesure de modifier votre tableau de dossiers.

C'est parce que votre modèle hériter de toutes les méthodes de la ActiveRecord::Base de Classe, qui définit déjà pour vous les rudiments CRUD accesseurs (Create, Read, Update, Delete). Ceci est expliqué sur la doc officiel ici Rails de Modèle et ici Écraser par défaut accesseur (défiler vers le bas pour le chapitre "Écraser par défaut accesseur")

Dire, par exemple : nous avons une table de base de données appelé "utilisateurs" qui contient trois colonnes "prénom", "nom" et "rôle" :

Les instructions SQL :

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

Je suppose que vous avez défini l'option config.active_record.whitelist_attributes = true dans votre config/environment/production.rb pour protéger votre application à partir de la mesure de Masse exploiter. C'est expliqué ici : Masse

Les Rails modèle fonctionne parfaitement avec le Modèle ci-dessous :

class User < ActiveRecord::Base

end

Cependant, vous aurez besoin de mettre à jour chaque attribut de l'utilisateur séparément dans votre contrôleur pour votre forme de la Vue de travail :

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 internationlization t method for the flash message
        flash[:success] = t('activerecord.successful.messages.updated', :model => User.model_name.human)
    end

    respond_with(@user)
end

Maintenant, afin de faciliter votre vie, vous ne voulez pas faire compliqué contrôleur pour l'Utilisateur de votre modèle. Si vous utilisez la attr_accessible méthode spéciale dans votre modèle de Classe :

class User < ActiveRecord::Base

  attr_accessible :firstname, :lastname

end

Ainsi, vous pouvez utiliser la fonction "autoroute" (masse assignement) pour mettre à jour :

def update
    @user = User.find_by_id(params[:id])

    if @user.update_attributes(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 ajouter le "rôle" des attributs de la attr_accessible liste parce que vous ne permettez pas à vos utilisateurs de définir par eux-mêmes de leur rôle (comme admin). Vous faire vous-même sur un autre admin View.

Si votre vue de l'utilisateur n'affiche pas un "rôle", un pirate peut facilement envoyer une requête HTTP de type POST qui incluent le "rôle" dans les params de hachage. Le manque de "rôle" de l'attribut sur la attr_accessible est de protéger votre application à partir de ce.

Vous pouvez toujours modifier votre nom d'utilisateur.l'attribut role sur sa propre comme ci-dessous, mais pas avec tous les attributs.

@user.role = DEFAULT_ROLE

MAINTENANT, pourquoi diable voulez-vous utiliser le attr_accessor ?

C'est dans le cas où votre formulaire utilisateur ne montrent un champ qui n'existe pas dans votre table des utilisateurs comme une colonne.

Par exemple, disons que votre utilisateur afficher un "s'il vous plaît, dites-le-admin-que-je suis-dans-ici". Vous ne voulez pas stocker ces informations dans votre table. Vous voulez juste que les Rails de vous envoyer un e-mail vous avertissant qu'un "fou" ;-) l'utilisateur a souscrit.

Pour être en mesure de faire usage de cette info dont vous avez besoin pour stocker temporairement quelque part. Quoi de plus facile que de récupérer d'un utilisateur.coucou attribut ?

Si vous ajoutez ce champ de votre modèle :

class User < ActiveRecord::Base

  attr_accessible :firstname, :lastname
  attr_accessor :peekaboo

end

De sorte que vous serez en mesure de faire de l'éducation de l'utilisation de l'utilisateur.coucou attribut quelque part dans votre contrôleur pour envoyer un e-mail ou de faire ce que vous voulez.

ActiveRecord ne sauvera pas le "coucou" de l'attribut dans votre table lorsque vous faites un "utilisateur.enregistrer" parce qu'elle ne voit pas toute la colonne correspondant à ce nom dans son modèle.

J'espère que cette claire à la question :o)

49voto

Joshua Cheek Points 9450

attr_accessor est une méthode Ruby qui vous donne setter et getter méthodes à 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 un Rails de la méthode qui détermine quelles variables peuvent être définies dans une masse d'affectation.

Lorsque vous soumettez un formulaire, et vous avez quelque chose comme MyModel.new params[:my_model] , alors vous voulez avoir un peu plus de contrôle, de sorte que les gens ne peuvent pas présenter les choses que vous ne voulez pas qu'ils.

Vous pourriez ne attr_accessible :email , de sorte que quand quelqu'un met à jour leur compte, ils peuvent changer leur adresse e-mail. Mais vous ne le ferais pas, attr_accessible :email, :salary parce que une personne pourrait définir leur salaire par la soumission d'un formulaire. En d'autres termes, ils pourraient pirater leur chemin à une relance.

Ce genre d'information doit être explicitement traitées. Juste de l'enlever de la forme n'est pas suffisant. Quelqu'un pourrait aller avec firebug et ajouter l'élément dans le formulaire pour soumettre un champ salaire. Ils pourraient utiliser le construit en roulage à soumettre un nouveau traitement pour le contrôleur de la méthode de mise à jour, ils pourraient créer un script qui envoie un post avec que des informations.

Donc, attr_accessor est sur la création de méthodes pour stocker des variables, et attr_accessible est à propos de la sécurité de la masse des affectations.

18voto

shrikant1712 Points 1835

attr_accessor est code ruby et est utilisé lorsque vous n'avez pas de colonne dans votre base de données, mais encore envie de montrer un champ dans vos formulaires. La seule façon de permettre c'est-à - attr_accessor :fieldname et vous pouvez utiliser ce champ dans votre Vue, ou d'un modèle, si vous voulez, mais surtout, de votre point de Vue.

attr_accessible vous permet de lister toutes les colonnes que vous souhaitez permettre de Masse, comme andy échappé ci-dessus. À l'opposé de ce qui est attr_protected ce qui signifie que ce domaine que je ne veux PAS que quiconque d'être admis à la Messe Céder à. Plus que probablement, il va être l'un des champs de la base de données que vous ne voulez pas que quiconque monkeying autour avec. Comme un champ de statut, ou de ce genre.

2voto

Manish Shrivastava Points 4380

En deux mots:

attr_accessor est getter, setter méthode. alors qu' attr_accessible est-à-dire un attribut particulier est accessible ou non. c'est tout.


Je tiens à ajouter que nous devrions utiliser une Forte paramètre au lieu de attr_accessible pour les protéger de la masse asignment.

Cheers!

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