2011-05-28 12 views
6

Me gustaría sobrescribir el setter para una asociación, pero write_attribute() no funciona, probablemente porque ese método solo funciona para las columnas de la base de datos.¿Cuál es el equivalente de write_attribute para asociaciones en Rails?

He intentado con super(), pero eso tampoco funciona (no pensé que ... pero valía la pena adivinarlo).

¿Cómo anulo el setter? Esto es lo que estoy tratando de hacer:

def parent=(value) 
    # this line needs to be changed 
    write_attribute(:parent, value) 

    if value.subject.start_with?('Re:') 
     self.subject = "#{value.subject}" 
    else 
     self.subject = "Re: #{value.subject}" 
    end 

    self.receivers << value.sender 
    end 

Respuesta

3

He encontrado una manera de hacerlo, pero estoy preocupado por ella:

alias_method :old_parent=, :parent= 

    def parent=(value) 
    self.old_parent = value 

    if value.subject.start_with?('Re:') 
     self.subject = "#{value.subject}" 
    else 
     self.subject = "Re: #{value.subject}" 
    end 

    self.receivers << value.sender 
    end 

Una cosa que no necesariamente gusta de rieles es que cada vez que desee hacer algo que está fuera de lo normal un poco, pero que no es irracional de ninguna manera, el "cómo" es muy diferente de lo que su intuición podría aportar.

No es un problema cuando conoce las excepciones, pero cuando está aprendiendo, este tipo de irregularidad e incoherencia sobre cómo hacer las cosas hace que sea más difícil de aprender, no más fácil.

Java puede ser inicialmente más difícil de aprender, pero es mucho más consistente. Su intuición puede llevarlo mucho más allá una vez que piense en Java. Esto no es verdad una vez que piensas en Rails. Rails se trata de la memorización de métodos para llamar y memorizar sobre cómo hacer cosas. En Java, puedes razonar mucho más ... y intellisense llena el resto.

Estoy decepcionado. Este es un patrón recurrente para mí: quiero hacer algo que sea simplemente "un poco más complejo" que los ejemplos del marco ... y el "cómo" es inconsistente y toma 30 minutos o tal vez incluso horas localizar y encontrar la respuesta para eso.

0

En lugar de

def parent=(value) 
    write_attribute(:parent, value) 
end 

¿No podrías hacer:

def parent=(parent) 
    parent_id = parent.id 
end 
11

lo que funcionó para mí es la siguiente:

def parent=(new_parent) 
    # do stuff before setting the new parent... 

    association(:parent).writer(new_parent) 
end 
3

En Rails 4.2.1 doc:

# Association methods are generated in a module that is included into the model class, 
# which allows you to easily override with your own methods and call the original 
# generated method with +super+. For example: 
# 
# class Car < ActiveRecord::Base 
#  belongs_to :owner 
#  belongs_to :old_owner 
#  def owner=(new_owner) 
#  self.old_owner = self.owner 
#  super 
#  end 
# end 
Cuestiones relacionadas