回形针:样式取决于模型(has_many多态图像)

atm*_*ell 10 ruby ruby-on-rails paperclip

我已经设置了我的模型以使用多态Image模型.这工作正常,但我想知道是否可以更改每个模型的:样式设置.找到一些使用STI的示例(模型<图像)但是这对我来说不是一个选项,因为我使用的是has_many关系.

艺术

has_many :images, :as => :imageable
Run Code Online (Sandbox Code Playgroud)

图片

belongs_to :imageable, :polymorphic => true
has_attached_file :file, :styles => { :thumb => "150x150>", :normal => "492x600>"}
                         #Change this setting depending on model
Run Code Online (Sandbox Code Playgroud)

UPDATE

我尝试在Proc方法中启动调试器.仅填充与附加文件相关的字段:

run'irb(Image):006:0> a.instance => #<Image id: nil, created_at: nil, updated_at: nil, imageable_id: nil, imageable_type: nil, file_file_name: "IMG_9834.JPG", file_content_type: "image/jpeg", file_file_size: 151326, file_updated_at: "2010-10-30 08:40:23">
Run Code Online (Sandbox Code Playgroud)

这是ImageController #create的对象

ImageController#create
@image => #<Image id: nil, created_at: nil, updated_at: nil, imageable_id: 83, imageable_type: "Art", file_file_name: "IMG_9834.JPG", file_content_type: "image/jpeg", file_file_size: 151326, file_updated_at: "2010-10-30 08:32:49">
Run Code Online (Sandbox Code Playgroud)

我正在使用paperclip(2.3.5)和Rails 3.0.1.无论我做什么,a.instance对象都是只有与填充的附件相关的字段的图像.有任何想法吗?

UPDATE2

在Paperclip论坛上阅读了很多内容后,我认为在保存实例之前无法访问该实例.你只能看到Paperclip的东西,就是这样.

我通过使用前置过滤器从图像控制器预先设置图像来解决这个问题 - 没有附件

  before_filter :presave_image, :only => :create

  ...

  private

  def presave_image
    if @image.id.nil? # Save if new record / Arts controller sets @image
      @image = Image.new(:imageable_type => params[:image][:imageable_type], :imageable_id => params[:image][:imageable_id])
      @image.save(:validate => false)
      @image.file = params[:file] # Set to params[:image][:file] if you edit an image.
    end
  end
Run Code Online (Sandbox Code Playgroud)

Mar*_*off 8

我在这里参加派对的时间非常晚,但是我想澄清一下有关访问此线程中发生的任何其他人的模型数据的事情.我刚刚使用Paperclip根据模型中的数据应用水印时遇到了这个问题,经过大量调查后才开始工作.

你说:

在Paperclip论坛上阅读了很多内容后,我认为在保存实例之前无法访问该实例.你只能看到Paperclip的东西,就是这样.

实际上,如果在分配附件之前已在对象中设置了模型数据,可以看到模型数据!

分配模型中的附件时,您的回形针处理器和诸如此类的东西会被调用.如果您依赖于质量分配(或实际上不是),只要为附件分配了一个值,回形针就可以完成它的工作.

这是我解决问题的方法:

在我带附件的模型(照片)中,除了附件外attr_accessible,我创建了所有属性,从而在批量分配期间保持附件的分配.

class Photo < ActiveRecord::Base
  attr_accessible :attribution, :latitude, :longitude, :activity_id, :seq_no, :approved, :caption

  has_attached_file :picture, ...
  ...
end
Run Code Online (Sandbox Code Playgroud)

在我的控制器的创建方法(例如)中,我picture从中拉出了params,然后创建了对象.(可能没有必要删除图片params,因为attr_accessible声明应该防止picture被分配,但它不会受到伤害).然后picture,设置了照片对象的所有其他属性之后,我分配属性.

def create
  picture = params[:photo].delete(:picture)
  @photo = Photo.new(params[:photo])
  @photo.picture = picture

  @photo.save
  ...
end
Run Code Online (Sandbox Code Playgroud)

在我的例子中,用于应用水印的图片调用的样式之一,即水印中保存的文本字符串attribution.在我更改代码之前,从未应用过属性字符串,并且在水印代码attachment.instance.attribution中始终如此nil.这里总结的变化使得整个模型在回形针处理器内可用.关键是最后分配您的附件属性.

希望这有助于某人.


mpo*_*lov 5

我在创建时找到了拾取样式的解决方法.关键是实现before_post_processafter_save挂钩.

class Image < ActiveRecord::Base

  DEFAULT_STYLES = {
    medium: "300x300>", thumb: "100x100>"
  }

  has_attached_file :file, styles: ->(file){ file.instance.styles }


  validates_attachment_content_type :file, :content_type => /\Aimage\/.*\Z/

  # Workaround to pickup styles from imageable model
  # paperclip starts processing before all attributes are in the model
  # so we start processing after saving

  before_post_process ->{
    !@file_reprocessed.nil?
  }

  after_save ->{
    if !@file_reprocessed && (file_updated_at_changed? || imageable_type_changed?)
      @file_reprocessed = true
      file.reprocess!
    end
  }


  belongs_to :imageable, polymorphic: true

  def styles
    if imageable_class.respond_to?(:image_styles)
      imageable_class.image_styles
    end || DEFAULT_STYLES
  end

  def imageable_class
    imageable_type.constantize if imageable_type.present?
  end


end
Run Code Online (Sandbox Code Playgroud)

所以你必须在imageable_class中定义image_styles类方法在我的情况下它是

class Property < ActiveRecord::Base

  def self.image_styles
    {
      large: "570x380#",
      thumb: "50x70#",
      medium: "300x200#"
    }
  end

end
Run Code Online (Sandbox Code Playgroud)