2012-03-02 11 views
8

sto cercando di fare qualcosa di simile:C'è un modo per sovrascrivere l'operatore << in Ruby?

account.users << User.new 

Ma ho bisogno che gli utenti siano un metodo su un conto. Quindi ho provato cose del tipo:

def users<<(obj) 

Ma non ho avuto fortuna con quello. È possibile farlo anche in Ruby? Assumerei così perché le relazioni ActiveRecord sembrano funzionare in questo modo in Rails.

+0

È questa associazione '' degli utenti Rails? – lulalala

risposta

1

In questo caso è il << della classe dell'utente. Quindi può essere un Array o un AssociationProxy.

Il mosto più semplice è creare un nuovo metodo per fare ciò che si desidera.

È possibile sovrascrivere il metodo in base all'istanza.

account.users.instance_eval do 
    def <<(x) 
    put 'add' 
    end 
end 

account.users << User.new 
# add 

ma è necessario farlo tutto il tempo prima di aggiungere da < <

0

users sarebbe restituire un oggetto che ha ignorato << operatore come Array, IO, String, o qualsiasi tipo si crea. Si ignora come questo:

class SomeType 
    def <<(obj) 
    puts "Appending #{obj}" 
    end 
end 
5

Sembra che si potrebbe non essere descrivendo il problema vero e proprio, ma di rispondere alla tua domanda - sì, si può ignorare il << dell'operatore:

class Foo 
    def <<(x) 
    puts "hi! #{x}" 
    end 
end 

f = Foo.new 
=> #<Foo:0x00000009b389f0> 
> f << "there" 
hi! there 
+0

Tuttavia non voglio usare la classe Foo. Voglio utente foo.users << x –

+0

@JohnBaker, 'foo.users << obj' è equivalente a' foo.users.send: <<, obj'. Dovresti semplicemente restituire la schiera di utenti a Foo; il metodo ['Array # <<'] (http://ruby-doc.org/core-1.9.3/Array.html#method-i-3C-3C) spingerà altri utenti nell'array. –

8

Controllare questa risposta: Rails: Overriding ActiveRecord association method

[questo codice è completamente dalla altra risposta, qui per i futuri ricercatori]

has_many :tags, :through => :taggings, :order => :name do 
    def << (value) 
     "overriden" #your code here 
    end  
    end 
0

Se si sta tentando di eseguire un'azione aggiungendo uno User alla raccolta users, è possibile utilizzare association callbacks invece di superare << (poiché esistono molti modi per aggiungere un oggetto a un'associazione).

class Account 
    has_many :users, :after_add => :on_user_add 

    def on_user_add(user) 
    p "Added user : #{user.name} to the account: #{name}" 
    end 
end 
1

presumo di avere un modello come questo:

class Account < ActiveRecord::Base 
    has_and_belongs_to_many :users 
end 

Per ignorare Account#users<<, è necessario definire in un blocco che si passa a has_and_belongs_to_many:

class Account < ActiveRecord::Base 
    has_and_belongs_to_many :users do 
    def <<(user) 
     # ... 
    end 
    end 
end 

Puoi accedere all'oggetto Account appropriato facendo riferimento a proxy_association.owner:

def <<(user) 
    account = proxy_association.owner 
end 

Per chiamare l'originale Account#users<<, chiamare Account#users.concat:

def <<(user) 
    account = proxy_association.owner 
    # user = do_something(user) 
    account.users.concat(user) 
end 

Per maggiori dettagli, si veda questa pagina: Association extensions - ActiveRecord

Problemi correlati