2013-04-11 14 views
15

probabilmente facendo qualcosa di stupido qui, ma ecco la mia base di classe cookie cutter:Rails 4 parametri forti in mancanza durante la creazione di istanze in consolle rotaie

class League < ActiveRecord::Base 

    private 
     def league_params 
     params.require(:full_name).permit! 
     end 

end 

E quando si crea una nuova istanza di Lega:

2.0.0-p0 :001 > l = League.new(full_name: 'foo', short_name: 'bar') 
WARNING: Can't mass-assign protected attributes for League: full_name, short_name 

Che cosa esattamente sto facendo di sbagliato qui? Si tratta di una costruzione 4.0.0.beta1 Rails + Rubino 2.0

** UPDATE **

Mi rendo conto ora che i parametri forti vengono applicate nel Controller ora e non nel modello. La domanda originale è ancora valida. Se sono consentiti a livello di controller, come posso autorizzare correttamente gli attributi se creo istanze nella console di Rails? Non avrei nemmeno bisogno di usare anche attr_accessible in questo caso, quindi duplicare completamente ciò che i parametri forti stanno cercando di "riparare"?

+0

Puoi pubblicare il tuo Gemfile? Anche il codice nel tuo modello? – Agis

+0

@randombits hai aggiornato il tuo progetto da rails3? – AKovtunov

risposta

14

Due cose. La definizione league_params va nel controller, non nel modello. E params.require() dovrebbe contenere il nome del modello che deve essere presente nei parametri, non gli attributi. Il controllo presenza attributi dovrebbe essere ancora presente nelle convalide del modello. Assicurati di voler davvero consentire l'accesso a tutti gli attributi nel modello di League prima di utilizzare permit!. Quindi, dovrebbe assomigliare a questo:

class LeaguesController < ApplicationController 

    private 
    def league_params 
     params.require(:league).permit! 
    end 

end 

Aggiornamento:

Sì, se si desidera che gli attributi per essere limitate quando si accede direttamente il modello, si avrebbe bisogno di tornare a utilizzare il attr_accessible nel modello . Questa funzionalità è stata spostata in questa gemma: https://github.com/rails/protected_attributes.

Penso che si presuma che se si sta lavorando con il modello direttamente nella console, non è necessario proteggere gli attributi come si sa esattamente cosa viene inserito. Dato che la console ha pieno accesso alla tua app, sarebbe altrettanto facile ingurgitare l'intero database come se fosse un attributo maligno.

+1

Cosa succede se il campionato non viene creato nel controller? Lo sto creando nella console in questo caso particolare. – randombits

+0

Quindi non è necessario utilizzare i parametri consentiti. I parametri consentiti vengono utilizzati per proteggere dai dati immessi dall'utente. – spullen

+3

quindi devo ricorrere comunque a attr_accessible? – randombits

7

La ragione di sicurezza di base per l'esistenza di entrambi i parametri forti e attr_accessible è che ci sono alcuni attributi nel modello che non dovrebbe essere permettono di essere cambiato a meno che non sia l'intenzione esplicita di codice.

La leggera differenza tra di loro è la forma prospettica che fanno il loro lavoro.

StrongParameters focus sul caso d'uso: l'azione di ciascun controller può essere regolata per consentire o impedire determinati parametri, tenendo in considerazione qualsiasi condizione. Totale flessibilità

attr_accessible prende una prospettiva diversa. Invece di concentrarsi sul caso d'uso, si concentra sui ruoli. Ad esempio, a seconda del ruolo dell'utente determinati attributi possono essere modificati o meno.


Il modo di usare StrongParameters è quello di applicare le require e permit le parole chiave sulla hash param.

require afferma che una chiave deve essere presente sull'hash params. require solleverà un'eccezione se non c'è una tale chiave.

permit indica che un campo è consentito. Qualsiasi chiave non consentita verrà rimossa dall'hash e quindi non verrà passata al modello mediante l'assegnazione di massa.

Modello

class League 
    attr_protected :final_price # Nobody can mass-assign the final price 
    attr_accessible :winner_name, :as => :jury 
end 

E il controller

class LeaguesController < ApplicationController 

Queste due azioni utilizzano StrongParameters

# A common user can create a league 
    def create 
    league = League.new(league_params) 
    league.final_price = 1000 
    league.save 
    redirect_to(league) 
    end 

    # But only the admin can publish a league 
    def publish_league 
    league = League.find(params[:id] 
    league.update_attributes(league_params_as_admin) 
    end 

questo usa attr_accessible

def publish_the_winner 
    league = League.find(params[:id] 
    # We would expect the current_user.role to return :jury. 
    league.assign_attributes(params[:league], :as => current_user.role) 
    end 

    private 
    def league_params 
     params.require(:league).permit(:name) 
    end 

    def league_params_as_admin 
     params.require(:league).permit(:name, :status) 
    end 

end 

Nella mia esperienza:

utilizzare la flessibilità dei parametri di forza per mettere a punto ciò che gli attributi possono essere di massa assegnato a ciascuno dei vostri controller.

Utilizzare l'onnipresenza di attr_accesible per assicurarsi che determinati attributi non possano essere assegnati in serie, a prescindere da cosa. Ad esempio, in un'attività Resque è possibile passare l'input dell'utente come parametro. Verificheresti che alcuni attributi non sono assegnati in serie usando attr_accesible.

Maggiori informazioni:

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

https://github.com/rails/strong_parameters

0

Se si chiama direttamente i vostri modelli, allora sì che sarà eludere qualsiasi logica è stato implementato nel vostro controller.

È tuttavia possibile chiamare i controller dalla console, quindi gli StrongParameters implementati in questo modo avranno effetto.

vedere How do I call controller/view methods from the console in Rails?

1

Sembra che la whitelist è attivo, anche se si esegue Rails 4. Ha fatto l'aggiornamento a Rails 4 da un Rails 3 app? Hai questo nel tuo config/application.rb?

config.active_record.whitelist_attributes = true 

Verificare che i parametri forti siano in vigore su tutti i modelli. Se lo sono, è possibile modificare questa impostazione su false.

Inoltre, controllare che non ci sia attr_accessible nel modello.

+0

Non sono l'autore dell'argomento, ma grazie. Quando ho aggiornato il mio progetto da Rails3 a Rails4, questo messaggio è stato mostrato. Ma se creo il progetto Rails 4 con lo stesso codice (anche nelle configurazioni), il messaggio non verrà mostrato. Non so perché, sembra un piccolo insetto. – AKovtunov

+0

Non è possibile aggiornarlo in modo trasparente, è necessaria l'assistenza degli sviluppatori. Credo che il poster originale debba aver aggiunto la gemma 'protected_attributes', altrimenti ci sarebbe stato un errore. (Forse l'errore ti dice di installare quella gemma, non ho il computer giusto davanti a me per controllare). Il modo migliore per eseguire l'aggiornamento a Rails 4 è utilizzare prima la gem di strong_parameters e passare attraverso tutti i controller e i modelli per lavorare nel nuovo modo, solo dopo aver aggiornato la gemma Rails. – clacke

+0

La configurazione del tuo progetto Rails 4 è la stessa? Sto indovinando che la linea di configurazione menzionata è mancante o impostata su false. – clacke

Problemi correlati