2011-02-09 70 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,但是当我在回形针处理器中时,我所看到的唯一一件事是Picture类。 (我的下一个想法是爬上堆栈试图获得父母的呼叫者,但这看起来对我来说很臭。你会怎么做?

+1

是`@ picture.attachable`之后你在做什么?你如何保存图片? – Zabba 2011-02-09 14:30:01

+1

self.attachable返回什么? `类图片 true; before_save:检查; def check;把self.attachable;结束;结束' – fl00r 2011-02-09 14:32:05

回答

1

我“解决”这个问题,并希望在这里发布,以便它可以帮助别人。我的解决方案是创建一个“父”方法图片类爬上堆栈,发现看起来像父母的东西。

警告:这是蹩脚的代码,应该不会在任何情况下使用。它适用于我,但我不能保证它不会在路上造成身体伤害。

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

这段代码确实是走了caller树寻找一个名为*_controller.rb祖先。如果它找到一个(它应该),那么它将该名称解析为一个应该是调用代码的父类的类。

BTW:我放弃了回形针和使用CarrierWave开始。它更容易完成这种事情,我能够在一半时间内完成它的工作。 Yea 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

我创建了一个插值来解决它。我的回形针模型是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>" }