¿Cuál es el código predeterminado para has_many mayor: unirse a través de la asignación de carriles?

StackOverflow https://stackoverflow.com/questions/1130642

Pregunta

Tengo un has_many básico: a través de relación que es bi-direccional:

calendars have many calendar_calendar_events
calendars have many events through calendar_calendar_events


events have many calendar_calendar_events
events have many calendars through calendar_calendar_events

Estoy queriendo asignar calendarios a un evento con la función básica que calendar_ids= has_many: a través de conjuntos hacia arriba, sin embargo, quiero anular esta función para añadir un poco de magia extra. He tenido una mirada a través de la fuente de los carriles y no puedo encontrar el código para esta función. Me pregunto si alguien me podría apuntar a la misma. Voy a continuación, anularlo para esta clase de añadir las cosas que yo quiero:)

¿Fue útil?

Solución

Puede encontrar el código fuente en el lib/active_record/associations.rb archivo en línea de 1295

    def collection_accessor_methods(reflection, association_proxy_class, writer = true)
      collection_reader_method(reflection, association_proxy_class)

      if writer
        define_method("#{reflection.name}=") do |new_value|
          # Loads proxy class instance (defined in collection_reader_method) if not already loaded
          association = send(reflection.name)
          association.replace(new_value)
          association
        end

        define_method("#{reflection.name.to_s.singularize}_ids=") do |new_value|
          ids = (new_value || []).reject { |nid| nid.blank? }
          send("#{reflection.name}=", reflection.class_name.constantize.find(ids))
        end
      end
    end

Definitivamente debe evitar sobrescribir este método para agregar tales cosas mágicas. Raíles ya es "demasiada magia" a veces. Yo sugeriría para crear un atributo virtual con toda su lógica personalizada por varias razones:

    métodos
  1. algunos otros carriles podrían basarse en la aplicación por defecto
  2. que se basan en una API específica que pudiera ir a cambiar en el futuro versiones ActiveRecord

Otros consejos

Después de un poco de una búsqueda he encontrado:

http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/collection_accessor_methods

No se parecía a lo que pensaba que se vería así, así que por eso probablemente me lo perdí. Terminé anulando el calendarios = método en lugar del método calendar_ids = y todo funciona bien.

En respuesta a la respuesta anterior, solía alias_method_chain para anular el colocador defecto y añadir mi función. Funciona bastante bien, aunque no estoy seguro de por qué tengo que enviar el método setter en lugar de usar normalmente. No parecía que trabajar, así que esto va a hacer:)

  def calendars_with_primary_calendar=(new_calendars)
    new_calendars << calendar unless new_record?
    send('calendars_without_primary_calendar=', new_calendars) # Not sure why we have to call it this way
  end

  alias_method_chain :calendars=, :primary_calendar
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top