2015-11-16 12 views
13

Sto lavorando a un'applicazione RubyonRails/ActiveAdmin. La mia versione RoR è la 4.2.5 e la versione AA è 1.0.0. Ho un modello Message come segue.Come aggiungere un attributo virtuale a un modello in Ruby on Rails?

class Message < ActiveRecord::Base 

    belongs_to :user 
    validates :user, :content, presence: true 

    def palindrome 
    # return true/false 
    end 

end 

Come vedete, io voglio avere un attributo di sola lettura palindrome che dipende solo dalla content del messaggio. Voglio che questo attributo sia trattato esattamente come un normale attributo. Per normale, intendo quando recupero i messaggi tramite rails console o il formato di messaggi json, voglio vedere un attributo palindrome nell'elenco. Mi piacerebbe anche avere un filtro per messaggio da questo attributo.

Non so come potrei ottenere questo.

risposta

10

nel modello, è possibile scrivere attribuire funzioni di accesso (lettura/scrittura) per l'attributo virtuale palindrome attribuire questo modo:

# attr_reader 
def palindrome 
    self[:palindrome] 
end 

# attr_writer 
def palindrome=(val) 
    self[:palindrome] = val 
end 

# virtual attribute 
def palindrome 
    #return true/false 
end 

E, come si utilizza Rails 4, si deve whitelist palindrome attributo come qualsiasi altro attributo del modello nella tua forte definizione param all'interno del tuo controller per poter assegnare in massa il valore di palindrome. Qualcosa del genere:

# your_controller.rb 
private 

def your_model_params 
    params.require(:message).permit(:palindrome) 
end 

Dai un'occhiata a questo RailsCast on Virtual Attributes. Anche se è un po 'vecchio, ma sarebbe utile per i concetti.

Nota:

Un attributo virtuale non verrà visualizzato nella lista param automaticamente. Ma dovresti essere in grado di accedervi tramite la console Rails in questo modo: Message.new.palindrome. Inoltre, puoi esporre questo attributo virtuale nella tua API JSON, ad esempio se stai usando Active Model Serializer, puoi avere: attribute palindrome nel tuo MessageSerializer e poi palindrome sarà esposto all'API JSON.

+0

Beh, grazie. Ho due domande. Innanzitutto, non voglio che questo attributo sia scrivibile poiché dipende solo dal valore di un altro attributo. Secondo, cosa valuta 'self [: palindrome]'? – moorara

+0

Se non è necessario scrivere il valore dell'attributo, non si utilizza il metodo setter e non è possibile aggiungerlo nella definizione del parametro forte. 'self [: palindrome]' ti darà il valore del palindromo di 'self' che è l'istanza del tuo oggetto modello. Questo è simile a 'model_instance.palindrome'. Spero che sia chiaro ora. Fammi sapere se hai altre domande. –

+0

Sei sicuro che questo verrà visualizzato nell'elenco dei parametri? L'attributo virtuale –

15

Rails in realtà consentono di create attributi virtuali in questo modo, che vi evita di dover creare manualmente metodi getter e setter:

attr_reader :palindrome #getter 
attr_writer :palindrome #setter 
attr_accessor :palindrome #both 

È inoltre possibile passare più argomenti anche:

attr_accessor :palindrome, :foo, :bar 
Problemi correlati