Viele Leute in diesem Thread und bei Google erklären sehr gut, dass attr_accessible
eine Whitelist von Attributen angegeben ist, die in großen Mengen aktualisiert werden dürfen ( alle Attribute eines Objektmodells gleichzeitig ). Dies dient hauptsächlich (und nur) dem Schutz Ihrer Anwendung aus "Massenauftrag" Piraten Exploit.
Dies wird hier im offiziellen Rails-Dokument: Massenzuweisung erläutert
attr_accessor
ist ein Ruby-Code zum (schnellen) Erstellen von Setter- und Getter-Methoden in einer Klasse. Das ist alles.
Als Erklärung fehlt nun, dass Sie beim Erstellen einer Verknüpfung zwischen einem (Rails-) Modell und einer Datenbanktabelle NIEMALS, NIEMALS, NIEMALS attr_accessor
in Ihrem Modell Setter und Getter erstellen müssen, um Ihre zu ändern Tabellenaufzeichnungen.
Dies liegt daran, dass Ihr Modell alle Methoden von der ActiveRecord::Base
Klasse erbt , die bereits grundlegende CRUD-Accessoren (Erstellen, Lesen, Aktualisieren, Löschen) für Sie definiert. Dies wird im offiziellen Dokument hier Rails Model und hier Überschreiben des Standard-Accessors erläutert (scrollen Sie nach unten zum Kapitel "Standard-Accessor überschreiben").
Sagen Sie zum Beispiel: Wir haben eine Datenbanktabelle namens "Benutzer", die drei Spalten "Vorname", "Nachname" und "Rolle" enthält:
SQL-Anweisungen:
CREATE TABLE users (
firstname string,
lastname string
role string
);
Ich ging davon aus, dass Sie die Option config.active_record.whitelist_attributes = true
in Ihrer config / environment / Production.rb festgelegt haben, um Ihre Anwendung vor dem Exploit der Massenzuweisung zu schützen. Dies wird hier erklärt: Massenzuordnung
Ihr Rails-Modell funktioniert perfekt mit dem folgenden Modell:
class User < ActiveRecord::Base
end
Sie müssen jedoch jedes Benutzerattribut in Ihrem Controller separat aktualisieren, damit die Ansicht Ihres Formulars funktioniert:
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
Um Ihnen das Leben zu erleichtern, möchten Sie keinen komplizierten Controller für Ihr Benutzermodell erstellen. Sie verwenden also die attr_accessible
spezielle Methode in Ihrem Klassenmodell:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
end
Sie können also die "Autobahn" (Massenzuweisung) verwenden, um Folgendes zu aktualisieren:
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
Sie haben die "Rollen" -Attribute nicht zur attr_accessible
Liste hinzugefügt, weil Sie nicht zulassen, dass Ihre Benutzer ihre Rolle selbst festlegen (wie z. B. admin). Sie tun dies selbst in einer anderen speziellen Administratoransicht.
Obwohl in Ihrer Benutzeransicht kein "Rollen" -Feld angezeigt wird, kann ein Pirat leicht eine HTTP-POST-Anforderung senden, die "Rolle" im Parameter-Hash enthält. Das fehlende "Rollen" -Attribut auf attr_accessible
soll Ihre Anwendung davor schützen.
Sie können Ihr user.role-Attribut weiterhin wie unten beschrieben ändern, jedoch nicht mit allen Attributen zusammen.
@user.role = DEFAULT_ROLE
Warum zum Teufel würdest du das benutzen attr_accessor
?
Nun, dies wäre der Fall, wenn Ihr Benutzerformular ein Feld, das in Ihrer Benutzertabelle nicht vorhanden ist, als Spalte anzeigt.
Angenommen, in Ihrer Benutzeransicht wird das Feld "Bitte sagen Sie dem Administrator, dass ich hier bin" angezeigt. Sie möchten diese Informationen nicht in Ihrer Tabelle speichern. Sie möchten nur, dass Rails Ihnen eine E-Mail sendet, in der Sie gewarnt werden, dass ein "verrückter" ;-) Benutzer sich angemeldet hat.
Um diese Informationen nutzen zu können, müssen Sie sie vorübergehend irgendwo speichern. Was ist einfacher, als es in einem user.peekaboo
Attribut wiederherzustellen ?
Also fügen Sie dieses Feld Ihrem Modell hinzu:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
attr_accessor :peekaboo
end
So können Sie das user.peekaboo
Attribut irgendwo in Ihrem Controller gründlich nutzen , um eine E-Mail zu senden oder zu tun, was Sie wollen.
ActiveRecord speichert das Attribut "peekaboo" nicht in Ihrer Tabelle, wenn Sie eine ausführen, user.save
da in ihrem Modell keine Spalte angezeigt wird, die diesem Namen entspricht.
attr_accessor
wird verwendet, um Getter- und Setter-Methoden zu generieren. In meiner Antwort auf eine vorherige Frage finden Sie eine ziemlich umfassende Erklärung zuattr_accessible
: stackoverflow.com/questions/2652907/…. Aktualisieren Sie dann Ihre Frage, wenn Sie danach weitere spezifische Details benötigen.