2012-08-16 17 views
39

Desidero aggiungere a un modello esistente alcuni attributi che non devono essere persistenti o mappati su una colonna di database. Esiste una soluzione per specificare tale cosa?Attributi del modello ActiveRecord non persistente

+0

Possibile duplicato di [Aggiunta di attributi di runtime aggiuntivi a un oggetto activerecord] (http://stackoverflow.com/questions/7584592/adding-extra-run-time-attribs-to-an-activerecord-object) – mlt

risposta

48

Ovviamente usare il buon vecchio rubino attr_accessor. Nel modello:

attr_accessor :foo, :bar 

Sarete in grado di fare:

object.foo = 'baz' 
object.foo #=> 'baz' 
+14

Come ottenere questo attributo nel formato JSON dell'oggetto? Supponiamo, voglio che questo attributo appaia nel JSON dell'oggetto sul lato client. Lo prenderò? per ora non lo capisco, anche se ho impostato questo nel mio metodo di creazione. Come farlo? – Yash

+0

E in Rails 4? – monteirobrena

+1

@monteirobrena stessa cosa – apneadiving

26

ho avuto lo stesso problema, ma avevo bisogno di bootstrap del modello, in modo l'attributo dovuto persistere dopo to_json è stato chiamato . Devi fare una cosa in più per questo.

Come affermato dal apneadiving, il modo più semplice per iniziare è quello di andare al modello e aggiungere:

attr_accessor :foo 

Quindi è possibile assegnare gli attributi desiderati. Ma per mantenere l'attributo stick è necessario cambiare il metodo degli attributi. Nel file del tuo modello aggiungi questo metodo:

def attributes 
    super.merge('foo' => self.foo) 
end 
1

Nel mio caso volevo utilizzare un join sinistro per popolare l'attributo personalizzato. Funziona se non aggiungo nulla ma voglio anche essere in grado di impostare l'attributo su un nuovo oggetto e ovviamente non esiste. Se aggiungo attr_accessor, restituisce sempre nil dopo un select. Ecco l'approccio con cui ho finito che funziona per l'impostazione di un nuovo oggetto e il recupero dal join sinistro.

after_initialize do 
    self.foo = nil unless @attributes.key?("foo") 
end 

def foo 
    @attributes["foo"] 
end 

def foo=(value) 
    @attributes["foo"] = value 
end 
+0

Non funziona più in Rails 4.2. '@ attributes' è ora un' ActiveRecord :: AttributeSet' che supporta '[]' ma non '[] ='. – davogones

5

Nel caso in cui qualcuno si sta chiedendo come rendere questo per la vista, utilizzare gli argomenti del metodo per il metodo di rendering, in questo modo:

render json: {results: results}, methods: [:my_attribute] 

Si prega di sapere che questo funziona solo se si imposta l'attr_accessor sul modello e impostare l'attributo nell'azione del controller, come spiegato dalla risposta selezionata.

Problemi correlati