2012-03-02 27 views
8

estoy tratando de hacer algo como:¿Hay alguna manera de anular el operador << en Ruby?

account.users << User.new 

pero necesito los usuarios ser un método en una cuenta. Así que he intentado cosas como:

def users<<(obj) 

Pero no he tenido suerte con eso. ¿Es esto posible de hacer en Ruby? Supongo que sí porque las relaciones ActiveRecord parecen funcionar de esta manera en Rails.

+0

¿Es esta asociación '' de los usuarios rieles? – lulalala

Respuesta

1

En este caso es el << de su clase de usuario. Entonces puede ser un Array o un AssociationProxy.

Lo más simple es crear un nuevo método para hacer lo que desee.

En su lugar, puede anular el método.

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

account.users << User.new 
# add 

pero se necesita hacer eso todo el tiempo antes de agregar por < <

0

users devolvería un objeto que ha anulado << operador como Array, IO, String, o de cualquier tipo que cree. Se reemplaza la siguiente manera:

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

Parece que usted no puede estar describiendo su problema real, pero para responder a su pregunta - sí se puede anular el operador <<:

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

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

Aunque no quiero usar la clase Foo. Quiero usar foo.users << x –

+0

@JohnBaker, 'foo.users << obj' es equivalente a' foo.users.send: <<, obj'. Simplemente debe devolver la matriz de usuarios de Foo; el método ['Array # <<'] (http://ruby-doc.org/core-1.9.3/Array.html#method-i-3C-3C) empujará a usuarios adicionales a la matriz. –

8

Comprobar esta respuesta: Rails: Overriding ActiveRecord association method

[este código es completamente de la otra respuesta, aquí por los investigadores futuros]

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

Si está intentando realizar una acción al agregar User a la colección users, puede usar association callbacks en lugar de << (ya que hay muchas maneras de agregar un objeto a una asociación).

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

que suponga que tiene un modelo como este:

class Account < ActiveRecord::Base 
    has_and_belongs_to_many :users 
end 

Para sustituir Account#users<<, es necesario definirlo en un bloque que se pasa a has_and_belongs_to_many:

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

Puede acceder al objeto apropiado Account refiriéndose al proxy_association.owner:

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

Para llamar el original Account#users<<, llame Account#users.concat:

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

Para más detalles, ver esta página: Association extensions - ActiveRecord

Cuestiones relacionadas