如何在保存多态对象的父级之前获取它?

时间:2011-02-09 14:24:10

标签: ruby-on-rails polymorphism paperclip

我有一个标准的多态关系,在保存它之前我需要知道它的父亲是谁。

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类。 :(我的下一个想法是爬上堆栈试图让父母打电话,但这对我来说似乎很臭。你会怎么做?

3 个答案:

答案 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>" }