2011-09-05 2 views
12

Esiste un modo per ignorare un setter o getter per un modello in Mongoid? Qualcosa di simile:Ignora i setter e i getter di un modello mongolo

class Project 
    include Mongoid::Document 
    field :name, :type => String 
    field :num_users, type: Integer, default: 0 
    key :name 
    has_and_belongs_to_many :users, class_name: "User", inverse_of: :projects 

    # This will not work 
    def name=(projectname) 
    @name = projectname.capitalize 
    end 
end 

in cui il metodo name può essere sovrascritta senza l'utilizzo di campi virtuali?

+0

correlati: http://stackoverflow.com/questions/6699503/mongoid-custom-setters-getters-and-super – marcgg

risposta

16
def name=(projectname) 
    self[:name] = projectname.capitalize 
end 
+1

@ user923636 non è possibile modificare il campo "_id" di un documento una volta creato. Quindi, se il nome del progetto viene modificato, dovrai cancellare il vecchio documento e crearne uno nuovo con il nome modificato. – rubish

23

migliore utilizzo

def name=(projectname) 
    super(projectname.capitalize) 
end 

metodo

self[:name] = projectname.capitalize 

può essere pericoloso, causa sovraccarico con esso può causare infinita ricorsione

+1

grazie ho ricevuto la ricorsione da sé [: nome]. super works – GTDev

+0

@GearHead Ho anche passato a super over timme (sembra migliore), anche se parti del mio codice usano ancora la notazione self [: name] e non ho ancora affrontato alcuna ricorsione fino ad ora. – rubish

+2

Come potrebbe funzionare 'super' se non ci sono super classi? 'Mongoid :: Document' è incluso come Modulo, sono confuso qui ... – tothemario

1

Ho avuto un problema simile con la necessità di sostituire il setter "utente" per una appartiene a: relazione utente. Ho trovato questa soluzione non solo per questo caso, ma per il wrapping di qualsiasi metodo già definito all'interno della stessa classe.

class Class 
    def wrap_method(name, &block) 
    existing = self.instance_method(name) 

    define_method name do |*args| 
     instance_exec(*args, existing ? existing.bind(self) : nil, &block) 
    end 
end 

Questo vi permette di effettuare le seguenti operazioni nella classe del modello:

wrap_method :user= do |value, wrapped| 
    wrapped.call(value) 
    #additional logic here 
end 
+0

Esattamente quello che stavo cercando, e bella soluzione. +1 – user2398029

+0

Non provare a reinventare la bicicletta. Usa alias_method_chain per questo. – sandrew

+0

grazie per questo! Avere problemi con i setter e i getter della relazione. Il commento di Sandrew mi ha fatto esaminare a_m_c e ho appreso il modulo # prepend di Ruby 2.0. Ottima soluzione e davvero pulita - http://dev.af83.com/2012/10/19/ruby-2-0-module-prepend.html –