2011-02-09 3 views
4

나는 표준 다형성 관계가 있으므로 저장하기 전에 부모가 누구인지 알아야합니다.다형성 객체가 저장되기 전에 어떻게 부모를 가져 옵니까?

Class Picture < AR::Base 
    belongs_to :attachable, :polymorphic => true 
end 

Class Person < AR::Base 
    has_many :pictures, :as => :attachable 
end 

Class Vehicle < AR::Base 
    has_many :pictures, :as => :attachable 
end 

나는 종이 클립을 통해 사진을 업로드 그리고 난 다른 사진 (예. 인격 사진이 있어야 폴라로이드 차량 사진 오버레이를해야 & 볼)로 다른 일을 할 필요가있는 프로세서를 구축 할 수 있습니다. 내 문제는 그림이 저장되기 전에 사람이나 차량과 관련이 있는지 알 수 없다는 것입니다.

내가 사람에게 & 차량에 "마커"를 넣으려고 했으므로 그 사람에게 appart라고 말할 수 있었지만 내가 Paperclip 프로세서에있을 때 Picture 클래스 만 보았습니다. :(다음 생각은 부모 호출자를 얻으려고 스택을 올라가는 것이지만 그것은 나에게 상당히 냄새가 난다. 어떻게하면 좋을까?

+1

가'@ picture.attachable' 필요하시면? 사진 저장은 어떻게하고 있니? – Zabba

+1

self.attachable은 무엇을 반환합니까? '클래스 그림 true; before_save : 확인; def 체크; self.attachable; 종료; end' – fl00r

+0

파일이 저장되기 전에 association은'nil'입니다; 파일을 처리하고 저장 한 후 self.attachable은 필요한 모든 것을 반환합니다. –

답변

1

나는이 문제를 "해결"을 원했다 다른 사람을 도울 수 있도록 여기에 게시하십시오. 내 솔루션은 "부모"메소드를 작성하는 것입니다. 스택을 올라가서 부모처럼 보이는 무언가를 발견 한 Picture 클래스.

경고 :이 코드는 진절머리 나며 어쨌든 사용하면 안됩니다. 그것은 나를 위해 일했지만, 언젠가는 길 아래로 육체적 인 해를 끼치 지 않을 것이라고 보장 할 수는 없습니다. 이 코드는 무엇을

caller.select {|i| i =~ /controller.rb/}.first.match(/\/.+_controller.rb/).to_s.split("/").last.split("_").first.classify.constantize 

*_controller.rb라는 이름의 조상을 찾는 caller 트리를 걸어이다. 하나를 찾으면 (그리고해야한다) 이름을 파싱하여 호출 코드의 부모 클래스 여야하는 클래스로 만든다. whew

BTW : 나는 Paperclip을 떨어 뜨리고 CarrierWave을 사용하기 시작했습니다. 이런 종류의 작업을 훨씬 쉽게 수행 할 수 있으며 시간의 절반 만에 작업을 수행 할 수있었습니다. 네 카리 웨이브!

5

다형성 연관에서 가져올 수 있어야합니다.

Class Picture < AR::Base 
    belongs_to :attachable, :polymorphic => true 

    before_create :apply_filter 

    private 

    def apply_filter 
    case attachable 
    when Person 
     #apply Person filter 
    when Vehicle 
     #apply Vehicle filter 
    end 
    end 
end 

또는 당신이 개체를 구축하고 비교해야 나던 그래서 그냥에게 연결 유형을 묻는 것이 아니라 단지 문자열 비교를 할 수는.

Class Picture < AR::Base 
    belongs_to :attachable, :polymorphic => true 

    before_create :apply_filter 

    private 

    def apply_filter 
    case attachable_type 
    when "Person" 
     #apply Person filter 
    when "Vehicle" 
     #apply Vehicle filter 
    end 
    end 
end 
+0

나는 당신의 생각을 좋아하지만, "attachable"와 "attachable_type"은 연관이 만들어지기 전에'nil'을 포함합니다. –

+0

어떻게 만듭니 까? 일반적으로'some_vehicle.pictures.new'와 같은 부모 객체로부터 새로운 객체를 초기화 할 것입니다.이렇게하면 이미 적절하게 연결된 새로운 개체를 얻을 수 있습니다. – Ben

+0

저는 첨부 파일을 처리하기 위해 Paperclip을 사용하고 있습니다. 그래서 나는 Paperclip의 어딘가에 그것의 어딘가에 있다고 가정합니다. –

0

해결하기 위해 보간을 만들었습니다. 내 클립 클립 모델은 Asset이고 Project는 상위 모델입니다. 프로젝트 모델에 속해 있으며 첨부 파일을 가질 수있는 기사와 같은 다른 모델이 있습니다.

Paperclip.interpolates :attachable_project_id do |attachment, style| 
    attachable = Asset.find(attachment.instance.id).attachable 
    if attachable.is_a?(Project) 
    project_id = attachable.id 
    else 
    project_id = attachable.project.id 
    end 
    return project_id 
end 

Paperclip.interpolates :attachable_class do |attachment, style| 
    Asset.find(attachment.instance.id).attachable.class 
end 

이 그리고 같은 모델을 사용 :

has_attached_file :data, 
    :path => "private/files/:attachable_project_id/:attachable_class/:id/:style/:basename.:extension", 
    :url => "/projects/:attachable_project_id/:attachable_class/:id/:style", 
    :styles => { :small => "150x150>" } 
관련 문제