Bulk Has_many의 기본 코드는 무엇입니까?
-
16-09-2019 - |
문제
나는 기본적인 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는 이미 "너무 많은 마법"입니다. 여러 가지 이유로 모든 사용자 정의 논리가있는 가상 속성을 만들 것을 제안합니다.
- 일부 다른 Rails 방법은 기본 구현에 의존 할 수 있습니다.
- 향후 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