Sto spostando il codice da un'applicazione incorporata in un framework PHP personalizzato non standard in Ruby on Rails (versione 3). Nella versione PHP tutti i controller sono davvero grossi, con modelli sottili, con cui sono sempre stato in disaccordo, quindi mi piace il modo in cui Rails fa la validazione a livello di modello, che è probabilmente il 90% di ciò che accade in questi grassi controller attualmente.Rails 3 Convalida ActiveRecord basata sulle autorizzazioni utente
Un problema che sto affrontando, e incerto su come risolvere comunque, è quello delle diverse regole di validazione basate su chi sta apportando la modifica al modello. Ad esempio, un amministratore o il creatore originale del record dovrebbe essere in grado di fare cose come contrassegnare un record come cancellato (soft delete) mentre tutti gli altri non dovrebbero.
class Something < ActiveRecord::Base
...
validates :deleted, :owned_by_active_user => true
...
end
class OwnedByActiveUserValidator < ActiveModel::EachValidator
validate_each(record, attr_name, attr_value)
# Bad idea to have the model know about things such as sessions?
unless active_user.admin? || active_user.own?(record)
record.errors.add :base, "You do not have permission to delete this record"
end
end
end
Dal momento che il modello stesso è (in teoria) all'oscuro dell'utente che sta facendo il cambiamento, qual è il "modo delle rotaie" per fare questo genere di cose? Devo impostare l'utente attivo come attributo virtuale sul record (non effettivamente salvato nel DB), o devo semplicemente eseguire questi controlli nel controller? Devo ammettere che è strano avere il modello che controlla i permessi sull'utente attivo e aggiunge complessità quando si tratta di testare il modello.
Uno dei motivi per cui sono desideroso di mantenere il più possibile nel modello, è perché voglio fornire sia un'API (accessibile tramite OAuth) sia un sito Web, senza duplicare troppo codice, come questi tipi di controlli delle autorizzazioni.
Grazie, devo essere d'accordo con te. I miei modelli dovrebbero comportarsi come gli viene detto (a condizione che la logica aziendale li consenta). I miei controllori dovrebbero decidere chi li dice. Mi limiterò ad astrarre i dettagli cruenti nel miglior modo possibile. – d11wtq
Dogma ... So che questo è il modo in cui è comunemente fatto, ma mi sembra che mettere direttamente il controllo di accesso nei modelli sia una soluzione elegante se si considera che i modelli siano il livello di API di dati/livello di regole aziendali. Evita anche di ripetere le stesse informazioni in più controller che toccano lo stesso modello.Anche l'uso di validatori per lo scopo sembra davvero comodo: può generare errori come "mi dispiace, non hai il permesso di modificare quel campo". Tuttavia, quel campo non avrebbe dovuto essere mostrato in primo luogo. Vorrei che esistesse una soluzione che permettesse l'introspezione per i costruttori di moduli. – odigity
È possibile creare classi del modello di modulo (non supportate dal database) che implementano la convalida e i metodi necessari dal generatore di moduli. – yfeldblum