ruby-on-rails - tutorial - ruby on rails wiki




Unterschied zwischen attr_accessor und attr_accessible (4)

In zwei Worten:

attr_accessor ist getter , setter Methode. während attr_accessible , dass ein bestimmtes Attribut zugänglich ist oder nicht. das ist es.

Ich möchte hinzufügen, dass wir Strong-Parameter anstelle von attr_accessible , um vor einer Massenausrichtung zu schützen.

Prost!

Was ist der Unterschied zwischen attr_accessor und attr_accessible in Rails? attr_accessor meinem Verständnis wird mit attr_accessor Getter- und Setter-Methoden für diese Variable erstellt, so dass wir auf die Variable wie Object.variable oder Object.variable = some_value .

Ich habe gelesen, dass attr_accessible diese spezifische Variable für die Außenwelt zugänglich macht. Kann mir bitte jemand sagen was der Unterschied ist


Viele Leute in diesem Thread und bei Google erklären sehr gut, dass attr_accessible eine Whitelist von Attributen spezifiziert, die in Bulk aktualisiert werden dürfen ( alle Attribute eines Objektmodells gleichzeitig zusammen ). Dies dient hauptsächlich (und nur) dem Schutz Ihrer Anwendung von "Mass Assignment" Pirate Exploit.

Dies wird hier auf dem offiziellen Rails-Dokument erklärt: Mass Assignment

attr_accessor ist ein Ruby-Code, um (schnell) Setter- und Getter-Methoden in einer Klasse zu erstellen. Das ist alles.

Nun, was als Erklärung fehlt, ist, dass wenn Sie irgendwie eine Verbindung zwischen einem (Rails) -Modell mit einer Datenbanktabelle erstellen, attr_accessor in Ihrem Modell benötigen, um Setter und Getter zu erstellen, um modifizieren zu können die Aufzeichnungen Ihres Tisches.

Dies liegt daran, dass Ihr Modell alle Methoden von der ActiveRecord::Base Klasse erbt, die bereits grundlegende CRUD-Zugriffsmethoden (Erstellen, Lesen, Aktualisieren, Löschen) für Sie definiert. Dies wird im offiziellen Dokument hier erklärt. Rails Model und hier Überschreibe Standard-Accessor (scrolle runter zum Kapitel "Default-Accessor überschreiben")

Sagen wir zum Beispiel: Wir haben eine Datenbanktabelle namens "users", die drei Spalten "firstname", "lastname" und "role" enthält:

SQL-Anweisungen:

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

Ich nahm an, dass Sie in Ihrer config.active_record.whitelist_attributes = true config / environment / production.rb die Option config.active_record.whitelist_attributes = true , um Ihre Anwendung vor Massenzugriffen zu schützen. Dies wird hier erklärt: Mass Assignment

Ihr Rails-Modell wird hier perfekt mit dem Model funktionieren:

class User < ActiveRecord::Base

end

Sie müssen jedoch jedes Attribut des Benutzers separat in Ihrem Controller 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

Jetzt, um Ihr Leben zu erleichtern, möchten Sie keinen komplizierten Controller für Ihr Benutzermodell erstellen. Sie verwenden also die spezielle Methode attr_accessible in Ihrem Klassenmodell:

class User < ActiveRecord::Base

  attr_accessible :firstname, :lastname

end

Sie können also die "Autobahn" (Massenzuordnung) zum Aktualisieren verwenden:

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 der attr_accessible Liste die Attribute "role" nicht attr_accessible weil Sie Ihren Benutzern nicht erlauben, ihre Rolle selbst zu setzen (wie admin). Sie tun dies selbst auf einer anderen speziellen Admin-Ansicht.

Obwohl Ihre Benutzeransicht kein "Rollen" -Feld anzeigt, könnte ein Pirat leicht eine HTTP-POST-Anfrage senden, die "Rolle" in den Params-Hash enthält. Das fehlende Attribut "role" auf attr_accessible schützt Ihre Anwendung attr_accessible .

Sie können Ihr user.role-Attribut weiterhin wie unten selbst ändern, aber nicht mit allen Attributen zusammen.

@user.role = DEFAULT_ROLE

Warum zum Teufel würdest du den attr_accessor ?

Nun, dies wäre in dem Fall, dass Ihr Benutzerformular ein Feld anzeigt, das in Ihrer Benutzertabelle nicht als Spalte existiert.

Angenommen, Ihre Benutzeransicht zeigt ein Feld "bitte-sagen-die-Admin-das-bin-ich-bin-hier" an. Sie möchten diese Informationen nicht in Ihrer Tabelle speichern. Du willst nur, dass Rails dir eine E-Mail schicken, die dich davor warnt, dass ein "verrückter" ;-) User abonniert hat.

Um diese Informationen nutzen zu können, müssen Sie sie vorübergehend zwischenspeichern. Was ist einfacher, als es in einem user.peekaboo Attribut user.peekaboo ?

Also fügst du dieses Feld zu deinem 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 user.peekaboo , um eine E-Mail zu senden oder was immer Sie wollen.

ActiveRecord speichert das "peekaboo" Attribut in Ihrer Tabelle nicht, wenn Sie eine user.save weil sie keine Spalte in ihrem Modell sieht, die diesem Namen entspricht.


attr_accessor ist eine Ruby-Methode, die Setter- und Getter-Methoden für eine Instanzvariable mit demselben Namen attr_accessor . So ist es gleichbedeutend mit

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

attr_accessible ist eine Rails-Methode, die festlegt, welche Variablen in einer Massenzuordnung gesetzt werden können.

Wenn Sie ein Formular MyModel.new params[:my_model] und Sie etwas wie MyModel.new params[:my_model] , möchten Sie ein bisschen mehr Kontrolle haben, damit Leute keine Dinge einreichen können, die Sie nicht wollen.

Sie könnten attr_accessible :email damit jemand, der sein Konto aktualisiert, seine E-Mail-Adresse ändern kann. Aber du würdest nicht tun attr_accessible :email, :salary denn dann könnte eine Person ihr Gehalt durch eine Formularübergabe festlegen. Mit anderen Worten, sie könnten sich ihren Weg zu einer Gehaltserhöhung bahnen.

Diese Art von Informationen muss explizit behandelt werden. Es ist nicht genug, es aus dem Formular zu entfernen. Jemand könnte mit Firebug hineingehen und das Element in das Formular einfügen, um ein Gehaltsfeld einzureichen. Sie könnten die eingebaute Curl verwenden, um ein neues Gehalt an die Controller-Update-Methode zu senden, sie könnten ein Skript erstellen, das einen Post mit diesen Informationen sendet.

So geht es bei attr_accessor darum, Methoden zum Speichern von Variablen zu attr_accessible , und bei attr_accessible geht es um die Sicherheit von Massenzuweisungen.


attr_accessor ist eine Ruby-Methode, die einen Getter und einen Setter macht. attr_accessible ist eine Rails-Methode, mit der Sie Werte an eine Massenzuordnung übergeben können: new(attrs) oder update_attributes(attrs) .

Hier ist eine Massenaufgabe:

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

Sie können sich vorstellen, dass die Bestellung auch einen Rabattcode hat, zB: price_off. Wenn Sie nicht: price_off als attr_accessible markieren, verhindern Sie, dass bösartiger Code so funktioniert:

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

Auch wenn Ihr Formular kein Feld für: price_off enthält, ist es standardmäßig in Ihrem Modell verfügbar. Dies bedeutet, dass ein präparierter POST diesen noch festlegen kann. Mit attr_accessible whitelists werden jene Dinge aufgelistet, die massenweise zugewiesen werden können.





ruby