2011-09-01 8 views
9

mio setup: Rails 3.0.9, Ruby 1.9.2Rails 3 aggiungere attributo virtuale dinamico

Ho le mie ragioni per fare questo, ma quello che mi serve è un modo per aggiungere un attributo virtuale a un gruppo di risultati ActiveRecord in modo dinamico. Ciò significa che non sto utilizzando attr_accessor nel modello e desidero invece aggiungere in modo dinamico attributi virtuali a un set di risultati.

Per esempio,

users = User.all 
#a user has following attributes: name, email, password 

Quello che mi piace fare è dire add (senza l'utilizzo di attr_accessor) un attributo virtuale status-users, è possibile?

risposta

15

Si dovrebbe fare questo:

users.each do |user| 
    user.instance_eval do 
    def status 
     instance_variable_get("@status") 
    end   
    def status=(val) 
     instance_variable_set("@status",val) 
    end 
    end 
end 
+0

questo non avrebbe funzionato, in quanto questo attributo non sarebbe persistito nel database – Tilo

+6

@Tilo: ovviamente non si sa che cosa è un attributo virtuale – apneadiving

+0

@Tilo: http://railscasts.com/episodes/16-virtual -attributi Vedrai che un attributo virtuale non dovrebbe essere salvato nel database – apneadiving

2

è possibile effettuare le seguenti operazioni:

aggiungere un attributo "extra", che sarà accessibile come un hash, e che memorizzerà eventuali attributi aggiuntivi/dinamiche - - e poi dire Rails a persistere che Hash tramite JSON in ActiveRecord o Mongo o qualsiasi altra cosa si utilizza

esempio:

class AddExtrasToUsers < ActiveRecord::Migration 
    def self.up 
    add_column :users, :extras, :text # do not use a binary type here! (rails bug) 
    end 
    ... 
end 

quindi nel modello aggiungi un'istruzione per "serializzare" quel nuovo attributo, ad es. che significa che è persistito come JSON

class User < ActiveRecord::Base 
... 
serialize :extras 
... 
end 

È ora possibile fare questo:

u = User.find 3 

    u.extras[:status] = 'valid' 
    u.save 

È possibile anche aggiungere un po 'di magia al modello d'uso, a guardare il Hash extra se si ottiene un method_missing() chiamata

Vedi anche: Google "Rails 3 serializzare"

+0

qui non stai definendo un comportamento 'attr_accessor'. – apneadiving

+0

rileggi la domanda di Bob - lui dice esplicitamente che non vuole usare attr_accessor – Tilo

+0

dice che non vuole impostare 'attr_accessor' nel modello, che è abbastanza diverso – apneadiving

1

Se i tuoi attributi sono di sola lettura, è anche possibile aggiungerli selezionandoli nella vostra base di dati quer y. I campi che appaiono nel risultato del risultato SQL saranno automaticamente aggiunti come attributi.

Esempi:

User.find_by_sql('users.*, (...) AS status') 
User.select('users.*, joined_table.status').join(...) 

Con questi esempi avrete tutti User attributi e un attributo aggiuntivo status.

1

si può semplicemente fare:

users.each { |user| user.class_eval { attr_accessor :status } } 

Tutti users avranno user.status e user.status = :new_status disponibili.