문제

나는 기본적인 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 기능 : 그러나 설정을 통해이 기능을 무시하고 추가 마법을 추가하고 싶습니다. Rails 소스를 살펴 보았고이 기능의 코드를 찾을 수 없습니다. 누군가가 나를 지적 할 수 있는지 궁금합니다. 그런 다음이 클래스가 원하는 것들을 추가하기 위해 그것을 무시할 것입니다 :)

도움이 되었습니까?

해결책

파일에서 소스 코드를 찾을 수 있습니다 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

마법을 추가하기 위해이 방법을 덮어 쓰지 않아야합니다. Rails는 이미 "너무 많은 마법"입니다. 여러 가지 이유로 모든 사용자 정의 논리가있는 가상 속성을 만들 것을 제안합니다.

  1. 일부 다른 Rails 방법은 기본 구현에 의존 할 수 있습니다.
  2. 향후 ActiveRecord 버전에서 변경 될 수있는 특정 API에 의존합니다.

다른 팁

약간의 사냥 후 나는 그것을 발견했다 :

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

그것은 내가 생각했던 것처럼 보이지 않았기 때문에 아마 내가 그것을 놓친 이유입니다. Calendar_ids = 메소드 대신 캘린더 = 메소드를 재정의했으며 모든 것이 잘 작동합니다.

위의 답변에 응답하여 alias_method_chain을 사용하여 기본 세터를 무시하고 내 기능을 추가했습니다. 메소드 세터를 정상적으로 사용하는 대신 메소드 세터를 보내야하는 이유를 잘 모르겠지만 잘 작동합니다. 그래도 작동하지 않았기 때문에 이것은 할 것입니다 :)

  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