run rails new migrations inner foreign create belong association and ruby-on-rails ruby activerecord override

ruby on rails - rails - Rieles: Anulación del método de asociación ActiveRecord



ruby and rails documentation (7)

Creo que quería def tags.<<(*new_tags) para la firma, que debería funcionar, o la siguiente que es equivalente y un poco más limpia si necesita anular múltiples métodos.

class << tags def <<(*new_tags) # rawr! end end

¿Hay alguna manera de anular uno de los métodos proporcionados por una asociación ActiveRecord?

Digamos, por ejemplo, que tengo el siguiente polimorfo típico has_many: a través de la asociación:

class Story < ActiveRecord::Base has_many :taggings, :as => :taggable has_many :tags, :through => :taggings, :order => :name end class Tag < ActiveRecord::Base has_many :taggings, :dependent => :destroy has_many :stories, :through => :taggings, :source => :taggable, :source_type => "Story" end

Como probablemente sepa, esto agrega una gran cantidad de métodos asociados al modelo Story como etiquetas, etiquetas <<, etiquetas =, etiquetas.empty ?, etc.

¿Cómo hago para anular uno de estos métodos? Específicamente el método de las etiquetas <<. Es bastante fácil anular los métodos de una clase normal, pero parece que no puedo encontrar información sobre cómo anular los métodos de asociación. Haciendo algo como

def tags<< *new_tags #do stuff end

produce un error de sintaxis cuando se llama así que obviamente no es tan simple.


Debería definir el método de etiquetas para devolver un objeto que tenga un método << .

Podrías hacerlo así, pero realmente no lo recomendaría. Sería mucho mejor que simplemente al agregar un método para su modelo que hace lo que desea, en lugar de tratar de reemplazar algo que ActiveRecord usa.

Esto esencialmente ejecuta el método de tags predeterminado agrega un método << al objeto resultante y devuelve ese objeto. Esto puede requerir un poco de recursos porque crea un nuevo método cada vez que lo ejecuta

def tags_with_append collection = tags_without_append def collection.<< (*arguments) ... end collection end # defines the method ''tags'' by aliasing ''tags_with_append'' alias_method_chain :tags, :append


El método que uso es extender la asociación. Puedes ver la forma en que manejo los atributos de ''cantidad'' aquí: https://gist.github.com/1399762

Básicamente, te permite simplemente hacer

has_many : tags, :through => : taggings, extend => QuantityAssociation

Sin saber exactamente qué esperas lograr anulando los métodos, es difícil saber si podrías hacer lo mismo.


Esto puede no ser útil en su caso, pero podría ser útil para otros que investigan esto.

Devolución de llamada de la asociación: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

Ejemplo de los documentos:

class Project has_and_belongs_to_many :developers, :after_add => :evaluate_velocity def evaluate_velocity(developer) ... end end

Ver también Extensiones de asociación:

class Account < ActiveRecord::Base has_many :people do def find_or_create_by_name(name) first_name, last_name = name.split(" ", 2) find_or_create_by_first_name_and_last_name(first_name, last_name) end end end person = Account.first.people.find_or_create_by_name("David Heinemeier Hansson") person.first_name # => "David" person.last_name # => "Heinemeier Hansson"


Puedes usar block con has_many para extender tu asociación con los métodos. Vea el comentario "Use un bloque para extender sus asociaciones" here .
Anular los métodos existentes también funciona, pero no sé si es una buena idea.

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


Si desea acceder al modelo en Rails 3.2, debe usar proxy_association.owner

Ejemplo:

class Author < ActiveRecord::Base has_many :books do def << (book) proxy_association.owner.add_book(book) end end def add_book (book) # do your thing here. end end

Ver documentation


Rails guía documentos sobre anular los métodos agregados directamente.

El problema de OP con anulación << es probablemente la única excepción a esto, por lo que sigue la respuesta principal . Pero no funcionaría para has_one = método de asignación o métodos getter.