我有一个标准的多态关系,在保存它之前我需要知道它的父亲是谁。
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
我正在通过Paperclip上传图片,我构建了一个处理器,需要对不同的图片做不同的事情(即,个人图片应该有宝丽来外观和车辆图片应该有叠加)。我的问题是,在保存图片之前,我不知道它是否与人员或车辆相关联。
我尝试在“人物”中加入“标记”。车辆,以便我可以告诉他们appart,但当我在Paperclip处理器时,我唯一看到的是Picture类。 :(我的下一个想法是爬上堆栈试图让父母打电话,但这对我来说似乎很臭。你会怎么做?
答案 0 :(得分: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
答案 1 :(得分:1)
我“解决了”这个问题并希望在此发布,以便它可以帮助其他人。我的解决方案是在Picture类上创建一个“父”方法,该方法爬上堆栈并找到看起来像是父类的东西。
警告:这是一个糟糕的代码,在任何情况下都不应该使用。它对我有用,但我无法保证它不会在未来的某个时候造成身体伤害。
caller.select {|i| i =~ /controller.rb/}.first.match(/\/.+_controller.rb/).to_s.split("/").last.split("_").first.classify.constantize
这段代码的作用是走向caller
树寻找名为*_controller.rb
的祖先。如果它找到一个(它应该),那么它将名称解析为一个类,该类应该是调用代码的父类。 呼
BTW:我放弃了Paperclip并开始使用CarrierWave。它更容易做到这一点,我能够在一半的时间内完成它。 Yea CarrierWave!
答案 2 :(得分: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>" }