Frage

Ich habe eine grundlegende has_many: durch Beziehung, die bi-direktionale ist:

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

Ich bin zu wollen Kalender auf ein Ereignis mit der Grund calendar_ids= Funktion zuweisen, die has_many: durch einrichtet, aber ich möchte diese Funktion außer Kraft setzen einige zusätzliche Magie hinzuzufügen. Ich habe einen Blick durch die Schienen Quelle hatte und nicht den Code für diese Funktion finden. Ich frage mich, wenn mich jemand darauf hinweisen könnte. Ich werde außer Kraft setzen es dann für diese Klasse das Material hinzuzufügen, das ich will:)

War es hilfreich?

Lösung

Sie können den Quellcode in der Datei lib/active_record/associations.rb in Zeile 1295

finden
    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

Sie sollten auf jeden Fall vermeiden, so diese Methode zu überschreiben magische Sachen hinzuzufügen. Rails ist bereits „zu viel Magie“ manchmal. Ich würde vorschlagen, ein virtuelles Attribut mit allen kundenspezifische Logik aus mehreren Gründen zu erstellen:

  1. einige andere Schienen Methoden könnten auf der Standardimplementierung verlassen
  2. setzen Sie auf eine bestimmte API, die in zukünftigen Versionen Active
  3. könnte sich ändern

Andere Tipps

Nach etwas einer Jagd ich es gefunden:

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

Es sah nicht so aus, was ich dachte, es aussehen würde, ist also, warum ich es wohl verpasst. Ich beendete die Kalender = Methode anstelle der calendar_ids = Methode überschrieben und alles funktioniert gut.

Als Reaktion auf die Antwort oben, habe ich alias_method_chain die Standard-Setter außer Kraft zu setzen und meine Funktion hinzuzufügen. Funktioniert ganz gut, obwohl ich nicht sicher bin, warum ich habe die Methode Setter zu senden, anstatt nur sie normalerweise verwendet wird. Es ist nicht zu funktionieren scheint aber so wird dies tun:)

  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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top