2013-02-08 10 views
16

Ho due modelli correlati, ad esempio Activity e Step. Activity has_many :steps e Step belongs_to :activity che significa che la tabella per steps ha una colonna activity_id.Previene la modifica di un campo nel modello Rails

Questo è in Hobo 1.3, quindi Rails 3.0.

Quello che voglio è quello di garantire che dopo Step creazione non è possibile spostare un passaggio all'altro Activity. Non vogliamo che il campo activity_id cambi.

Ho rimosso il campo dai moduli di modifica, ma sto cercando un vincolo più forte. Essenzialmente voglio verificare su update (non su create) che la colonna non sia stata toccata. La documentazione di Hobo non suggerisce nulla del genere all'interno di Hobo, quindi guardo allo Rails validations, ma finora non ho trovato il vincolo "solo fare questo su aggiornamento" che ricordo, né una convalida che qualcosa non sia mutevole.

risposta

29

È possibile dichiarare un attributo come read_only con attr_readonly :your_field_name. Ma questo non creerà un errore se provate a scrivere questo attributo, fallirà silenziosamente. (Questo attributo verrà ignorata per tutto SQL-aggiornamenti)

Un'altra opzione potrebbe essere, per scrivere la convalida per questo caso, potrebbe essere simile a questo:

class Step < ActiveRecord::Base 
    validate :activity_id_not_changed 

    private 

    def activity_id_not_changed 
    if activity_id_changed? && self.persisted? 
     errors.add(:activity_id, "Change of activity_id not allowed!") 
    end 
    end 
end 

persisted? restituisce vero, se questo non è un nuovo record e non è distrutto.

vicini:

http://api.rubyonrails.org/classes/ActiveRecord/ReadonlyAttributes/ClassMethods.html#method-i-readonly_attributes

http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-persisted-3F

+0

'attr_readonly' funziona come pubblicizzato, b ut potrebbe causare una ruga con un altro aspetto dell'app. Proverò l'approccio di convalida domani e vedrò se funziona meglio. – pjmorse

+0

Se è davvero necessario modificare l'ID da qualche altra parte nell'applicazione, è possibile farlo anche con l'approccio di convalida con il seguente: 'step.save (: validate => false)' – Deradon

+0

Non si tratta di un problema di modifica altrove; è una copia di un oggetto. (Quindi, ipoteticamente, abbiamo copiato ipoteticamente l'attività in un modo che ha copiato anche tutti i passaggi, per qualche motivo non funziona, e non ho ancora scavato a fondo nel codice della copia per capire se questo cambiamento lo ha spezzato .) – pjmorse

1

penso che si può fare anche questo con il sistema di autorizzazioni Hobo: http://hobocentral.net/manual/permissions

Ad esempio:

def update_permitted? 
    acting_user.administrator && !activity_id_changed? 
end 
Problemi correlati