0

나는 엔진에서 일하고 있어요 통해 연결을 만들 수 있습니다. 내가 뭘 하려는지는 동적으로 허가 제휴를 소스로 사용하는 사용자에 대한 연관을 만들고, 같은 작업을 수행하여 다른 모델의 체인 연결을 만듭니다. 허용이 많은 모델에 포함됩니다, 실제로자동으로 많은 기존의 협회

class Person 
    has_many :group_permits, through: :person, source: :permits 
end 

class User 
    has_many :person_permits, through: :person, source: :permits, class_name: Permit 
    has_many :person_group_permits, through: :person, source: :group_permits, class_name: Permit 
end 

그러나, 그래서 사용자에 (실제로는 다른 모듈에서 클래스 메소드를 작성하려고 해요 :이와 (레일 3.1 이상)를 수동으로 수행 할 수 있습니다 , User.reflect_on_all_associations를 트래버스하고 많은 연관성이있는 새로운 연관 배열을 생성 할 수있는 더 많은 것들을 혼동 할 필요는 없습니다.

레일에서 이것을 올바르게 수행하는 방법에 대한 정보를 찾으십시오. 3.2.8. 나는 (구현 코드는 질문에 주어진 세부 사항과 약간 다름) 그것을 어떻게 여기

답변

0

은 다음과 같습니다

모듈 Authorisable 데프 self.included (기본) base.class_eval가 base.extend의 ​​ClassMethods에게 끝을 끝

module ClassMethods 
    class PermissionAssociationBuilder 
    def build_permissions_associations(klass) 
     chains = build_chains_from(klass) 
     chains.select! {|c| c.last.klass.included_modules.include? DistributedAuthorisation::Permissible} 
     permissions_associations = [] 
     chains.each do |chain| 
     source_name = :permissions 
     chain.reverse.each do |r| 
      assoc_name = :"#{r.name}_#{source_name}" 
      r.active_record.has_many assoc_name, through: r.name.to_sym, source: source_name, class_name: DistributedAuthorisation::Permission 
      source_name = assoc_name 
     end 
     permissions_associations << source_name 
     end 
     return permissions_associations 
    end 

    private 

    def build_chains_from(klass) 
     chains = reflections_to_follow(klass).map {|r| [r]} 
     chains.each do |chain| 
     models = chain.map {|r| r.klass}.unshift klass 
     reflections_to_follow(models.last).each do |r| 
      chains << (chain.clone << r) unless models.include? r.klass 
     end 
     end 
    end 

    def reflections_to_follow(klass) 
     refs = klass.reflect_on_all_associations 
     refs.reject {|r| r.options[:polymorphic] or r.is_a? ActiveRecord::Reflection::ThroughReflection} 
    end 
    end 

    def permissions_associations 
    @permissions_associations ||= PermissionAssociationBuilder.new.build_permissions_associations(self) 
    end 
end 

아마 아닐 가장 효율적인 방법은,하지만 내가 Klass.permissions_associations와 후있어 체인을 추가하고, 클래스 인스턴스 변수에 자신의 심볼을 저장합니다.

개선 방법에 대한 제안을 보내 주시면 기쁘게 생각합니다.