“ATTENZIONE: imansible assegnare in massa attributi protetti”

Ho usato tecniche RESTful per generare un modello (infatti, sto usando Devise gem, che lo fa per me), e ho aggiunto nuovi campi chiamati first_name e last_name al modello. La migrazione è andata bene. Ho aggiunto attr_accessor: first_name,: last_name al modello e mi aspettavo che avrebbe funzionato. Ma quando provo ad assegnare in massa nuove istanze con Doctor.create ({: first_name => “MyName”}) ecc., Sto ricevendo errori che dicono che non posso assegnare in massa attributi protetti.

Ho pensato che l’intero punto di utilizzo di attr_accessor fosse quello di aggirare la protezione dei campi di un modello. Puoi aiutarmi a dare un senso a questo messaggio?

Modifica: oh, e tra l’altro anche i record non vengono creati. Ho pensato che dovrebbero essere poiché questo è solo un avvertimento, ma non sono nel database.

Edit2: ecco il mio modello

class Doctor  :patients validates_presence_of :invitations, :on => :create, :message => "can't be blank" attr_accessor :invitations end 

e lo schema, che non ha il nome e il cognome perché sono creati nella tabella degli utenti, che è l’antenato dei medici. Ho usato l’ereditarietà di una tabella singola.

 create_table :doctors do |t| t.integer :invitations t.timestamps end 

e questa è la migrazione per cambiare la tabella degli utenti

 add_column :users, :first_name, :string add_column :users, :last_name, :string add_column :users, :type, :string 

EDIT: ecco il file seme. Non sto includendo il metodo truncate_db_table, ma funziona.

 %w{doctors patients}.each do |m| truncate_db_table(m) end Doctor.create(:invitations=>5, :email=>"[email protected]", :first_name=>"Name", :last_name=>"LastName") Patient.create(:doctor_id=>1, :gender=>"male", :date_of_birth=>"1991-02-24") 

Non confondere attr_accessor con attr_accessible . Accessor è incorporato in Ruby e definisce un metodo getter – model_instance.foo # returns something – e un metodo setter – model_instance.foo = 'bar' .

Accessibile è definito da Rails e rende l’attributo di massa assegnabile (fa l’opposto di attr_protected ).

Se first_name è un campo nella tabella del database del modello, quindi Rails ha già definito getter e setter per quell’attributo. Tutto quello che devi fare è aggiungere attr_accessible :first_name .

Per hackerare la tua app insieme in un modo insicuro totalmente inadatto alla modalità di produzione:

Vai a /config/application.rb Scorri verso il basso verso la fine dove troverai

 {config.active_record.whitelist_attributes = true} 

Impostalo su falso.

EDIT / btw (dopo 4 mesi di lavoro intensivo di ruby ​​incluso un workshop di 11 settimane): DHH crede che, per i noobies (le sue parole), “attivo e funzionante” sia più importante di “molto sicuro”.

SIA CONSIGLIATO: Anche se questa risposta (il mio primissimo stackoverflow credo) ora è a +6, è stata pari a -4 nella sua storia, il significato di ciò è che molti sviluppatori esperti di rail si sono sentiti molto appassionati a non volere tu per farlo.

AGGIORNAMENTO: 3 anni dopo, un altro modo per farlo – di nuovo, non sicuro, ma migliore della soluzione di cui sopra, probabilmente perché devi farlo per ogni modello

 class ModelName < ActiveRecord::Base column_names.each do |col| attr_accessible col.to_sym end ... end 

Non usare attr_accessor qui. ActiveRecord crea quelli automaticamente sul modello. Inoltre, ActiveRecord non creerà un record se viene lanciata una convalida o un errore di assegnazione di massa.

EDIT: non è necessaria una tabella di medici, è necessaria una tabella utenti con una colonna di tipo per gestire l’ ereditarietà di tabelle singole Rails. Gli inviti saranno sulla tabella degli utenti. Ah, vedo nel tuo esempio di codice aggiunto che hai tipo sugli utenti. Sbarazzati della tabella dei medici, sposta gli inviti agli utenti e penso che dovresti essere ok. Inoltre sbarazzarsi del attr_accessor. Non necessario.

Tieni presente che le rotaie STI utilizza la stessa tabella per tutte le classi e sottoclassi di un particolare modello. Tutti i record del tuo dottore saranno righe nella tabella degli utenti con un tipo di “dottore”

EDIT: Inoltre, sei sicuro di voler solo convalidare la presenza di inviti alla creazione e non gli aggiornamenti?

Aggiungi attr_accessible : variable1, variable2 al file di percorso della tabella.

D’accordo con la risposta di @Robert Speicher Ma raccomanderò caldamente di utilizzare il parametro Strong invece di attr_accessible per proteggere dall’assegnazione di massa.

Saluti!