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)