ما هو الكود الافتراضي للسائبة Has_many: من خلال "إرساء" في القضبان؟

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

سؤال

لدي أساسي has_many: من خلال العلاقة التي هي ثنائية الاتجاه:

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

أنا أريد تعيين التقاويم إلى حدث مع الأساسي calendar_ids= الوظيفة التي has_many: من خلال الإعدادات، ومع ذلك، أريد أن أتجاوز هذه الوظيفة لإضافة بعض السحر الإضافي. لقد ألقيت نظرة عبر مصدر القضبان ولا يمكنني العثور على رمز لهذه الوظيفة. أنا أتساءل عما إذا كان شخص ما يمكن أن يشيرني إليها. سألتجه بعد ذلك على هذا الفصل لإضافة الأشياء التي أريدها :)

هل كانت مفيدة؟

المحلول

يمكنك العثور على شفرة المصدر في الملف lib/active_record/associations.rb في الخط 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

يجب عليك بالتأكيد تجنب الكتابة فوق هذه الطريقة لإضافة أشياء سحرية. القضبان بالفعل "الكثير من السحر" في بعض الأحيان. أود أن أقترح إنشاء سمة افتراضية مع جميع المنطق المخصص لعدة أسباب:

  1. قد تعتمد بعض أساليب القضبان الأخرى على التنفيذ الافتراضي
  2. أنت تعتمد على واجهة برمجة تطبيقية محددة قد تتغير في إصدارات Activerecord المستقبلية

نصائح أخرى

بعد القليل من مطاردة وجدت ذلك:

http://apidock.com/rains/activerecord/associations/classmethods/collection_accessor_methods.

لم يكن يبدو وكأنه ما اعتقدت أنه سيظهر، ولهذا السبب فقد فاتني ذلك. انتهى بي الأمر إلى تجاوز التقويمات = الطريقة بدلا من التقويم = الطريقة وكل شيء يعمل بشكل جيد.

استجابة للإجابة أعلاه، استخدمت Alias_method_chain لتجاوز STERTER الافتراضي وإضافة ميزة التشغيل الخاصة بي. يعمل بشكل جيد للغاية، رغم أنني لست متأكدا من السبب في أن علي إرسال طريقة تشغيل الطريقة بدلا من استخدامها بشكل طبيعي. لا يبدو أنه يعمل على الرغم من أن هذا سيفعل :)

  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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top