2012-05-13 14 views
24

Wenn ich versuche, den folgenden Code auszuführen:ActiveModel :: MassAssignmentSecurity :: Fehler: keine Massen assign geschützt Attribute

hassle = rota.hassles.create(:sender => user1, :receiver => user2, :type => "sms") 

ich folgende Fehler obain:

Failure/Error: hassle = rota.hassles.create(:sender => user1, :receiver => user2, :type => "sms") 
ActiveModel::MassAssignmentSecurity::Error: 
    Can't mass-assign protected attributes: type 

Ich bin nicht sicher, was das bedeutet. Ich habe den: type als obligatorisch gemacht, wenn ich ihn also entferne, erhalte ich einen SQL-Fehler.

+3

Die Spalte „Typ“ standardmäßig von Schienen für STI verwendet wird. Die beste Lösung besteht darin, die Typspalte in etwas anderes umzubenennen. Eine nicht empfohlene Problemumgehung besteht darin, Ihre Modelldatei hinzuzufügen. Self.inheritance_column =: some_other_column_that_might_not_exists – bcd

+0

Ja - Informationen dazu, wie Sie das STI-Problem umgehen können, indem Sie die Spalte "type" verwenden: http://stackoverflow.com/questions/7134559/rails-use-type-column-ohne-sti (obwohl eine bessere Option sein könnte, den Namen der Spalte zu ändern). –

+0

yeah - Ich bin auf dieses Problem gestoßen. Geänderter Spaltenname Danke! – Karan

Antwort

59

Ein paar Dinge:

Massenzuordnung bedeutet in der Regel Attribute in den Anruf vorbei, die ein Objekt als Teil eines Attribute erstellt Hash. Das heißt, Sie übergeben eine Reihe von Attributen in einem Hash in den Aufruf, der das neue Objekt erstellt. Zum Beispiel:

@user = User.create({:name => "My name", :user_type => "nice_user"}) 

jedoch Rails enthält einige grundlegende Regeln, die Sicherheit nicht alle Attribute bedeuten kann standardmäßig auf diese Weise zugewiesen werden. Sie müssen angeben, welche im Voraus können. Sie tun so wie folgt aus:

class User < ActiveRecord::Base 
    attr_accessible :name, :user_type 
end 

Wenn Sie ein Attribut nicht spezifiziere ist attr_accessible, und Sie geben es in das Objekt zu erstellen, erhalten Sie den Fehler Sie auf dem Laufenden.

Hier sind weitere Details:

http://api.rubyonrails.org/v3.2.9/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html

Die Alternative einige der Attribute zu setzen ist, wenn Sie zuerst den Datensatz erstellen, und setzen Sie andere nach - etwa so:

# In this example `user_type` is not attr_accessible so it needs to be set specifically 
@user = User.create({:name => "My name"}) 
@user.user_type = "nice_user" 
@user.save 

Wenn Sie Probleme bei der Verwendung des Spaltennamens type haben, weil rails verwirrt ist und denkt, dass Sie Single Table Inheritance (STI) verwenden möchten, überprüfen Sie die Antwort auf diese Frage, um zu sehen, wie Sie damit umgehen können: http://guides.rubyonrails.org/

+0

danke ... hat perfekt funktioniert! –

+0

Was ist, wenn Sie versuchen, einen Elternteil mit vielen Kindern auf einmal zu erstellen? z.B; 'Post.create (comments)' – tokhi

0

Here ist eine Information darüber, was Massenzuweisung in Rails ist und warum der Schutz vorhanden ist. Es ist ziemlich einfach zu umgehen, wenn Sie wirklich ein geschütztes Attribut zuweisen möchten, aber es braucht ein paar zusätzliche Zeilen.

hassle = rota.hassles.build(:sender => user1, :receiver => user2) 
hassle.type = 'sms' 
hassle.save 
+0

hassle.type = 'sms' wird höchstwahrscheinlich eine Sms-Klasse auslösen existiert nicht Ausnahme – bcd

+0

Vielleicht. Ich arbeite unter der Annahme, dass OP weiß, was er mit STI macht. – x1a4

7

Arbeiten Sie mit Rails 3.2, während Sie einem 3.1-Lernprogramm wie der "Agile Web Development with Rails" 4. Ausgabe von Pragmatic Programmer folgen? Dann überprüfen Sie http://guides.rubyonrails.org/3_2_release_notes.html.

Ihr Problem ist, dass von Rails 3.1 bis 3.2 die Überprüfung des Massenzuweisungsschutzes für Active Record-Modelle standardmäßig auf 'strict' gesetzt ist. Kommentieren Sie die entsprechenden Zeilen in diesen Dateien:

config/environments/development.rb 
config/environments/test.rb 

... und Sie sind gut weiter zu lernen.Denken Sie daran, dies in der Tat zu lassen, wenn Sie Ihre erste Produktion Anwendung Codierung :)

+0

"Arbeiten Sie mit Rails 3.2, während Sie einem 3.1-Lernprogramm wie der" Agile Web Development with Rails "4. Ausgabe von Pragmatic Programmer folgen?" Genau das mache ich. +1 für die Behebung meines Problems. –

+0

Das behebt mein Problem, ich habe diese Zeile auskommentiert: 'config.active_record.mass_assignment_sanitizer =: strict' – mrzmyr

5
  1. Bitte versuchen: open config/application.rb

  2. Suchen Sie die Zeile von config.active_record.whitelist_attributes = true

  3. ändern true in false

Dann wird es dir gut gehen.

PS: Denken Sie daran, die Rails-Konsole neu zu starten.

2

Sie sollten einen weiteren Fehler erhalten, wie folgt: Spalte 'Typ' ist reserviert für die Speicherung der Klasse im Falle der Vererbung. Weil Spalte 'type' nicht in der aktiven Datensatzdatenbank verwendet werden sollte.

0

Ich benutze whitelist_attributes nicht, da Fälle Gebrauch, wenn ich will, um Massenzuweisung ist für meine interne Logik zu ermöglichen und in der Regel nicht direkt in Controller für CRUD Aktionen. Ich schlage vor, in diesen Fällen starke params zu verwenden. Aber wenn man die Massenzuordnung für bestimmte Modell aktivieren möchten tun Sie

class Foo < ActiveRecord::Base 
    # disables mass-assigment 
    attr_protected 
end 

Diese im Grunde setzt attr_protected auf leeres Array ([])

Verwandte Themen