条件转换选项回形针

时间:2014-04-22 13:33:29

标签: ruby-on-rails paperclip

some research之后,我可以根据我的image_class列添加样式。

Model.rb

has_attached_file :image,
                  :styles => lambda { |attachment| attachment.instance.decide_styles }

def decide_styles
  styles = {}

  case self.image_class
    when "poster"
      styles[:thumb] = ["30x45!", :jpg]
      styles[:standard] = ["185x278!", :jpg]
      styles[:expanded] = ["372x559!", :jpg]
      styles[:big] = ["600x900!", :jpg]
    when "cover"
      styles[:thumb] = ["30x45!", :jpg]
      styles[:standard] = ["300x1200!", :jpg]
  end

  styles
end

这很顺利,现在我想添加条件 convert_options 。这种方式失败了。

has_attached_file :image,
                  :styles => lambda { |attachment| attachment.instance.decide_styles }, 
                  :convert_options => lambda { |attachment| attachment.instance.decide_convert_options }

def decide_styles
  ...
end

def decide_convert_options

  opshunz = {}
  case self.image_class
    when "poster"
      opshunz[:thumb] = "-flop"
      opshunz[:standard] = "-flop"
      opshunz[:expanded] = "-flop"
      opshunz[:big] = "-flop"

    when "cover"
      opshunz[:thumb] = "-enhance"
      opshunz[:standard] = "-enhance"
  end

  opshunz
end

错误:

NoMethodError: undefined method `instance' for :all:Symbol

from /Users/AnsPoluke/Sites/nulike/app/models/movie_image.rb:8:in `block in <class:MovieImage>'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/attachment.rb:431:in `[]'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/attachment.rb:431:in `process_options'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/attachment.rb:423:in `extra_options_for'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/style.rb:56:in `convert_options'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/style.rb:79:in `block in processor_options'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/style.rb:78:in `each'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/style.rb:78:in `processor_options'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/attachment.rb:462:in `block in post_process_style'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/attachment.rb:461:in `each'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/attachment.rb:461:in `inject'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/attachment.rb:461:in `post_process_style'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/attachment.rb:454:in `block in post_process_styles'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/attachment.rb:453:in `each'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/attachment.rb:453:in `post_process_styles'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/attachment.rb:445:in `block (2 levels) in post_process'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/activesupport-4.0.2/lib/active_support/callbacks.rb:393:in `_run__3861360263242897910__image_post_process__callbacks'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/activesupport-4.0.2/lib/active_support/callbacks.rb:80:in `run_callbacks'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/callbacks.rb:36:in `run_paperclip_callbacks'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/attachment.rb:443:in `block in post_process'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/activesupport-4.0.2/lib/active_support/callbacks.rb:383:in `_run__3861360263242897910__post_process__callbacks'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/activesupport-4.0.2/lib/active_support/callbacks.rb:80:in `run_callbacks'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/callbacks.rb:36:in `run_paperclip_callbacks'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/attachment.rb:442:in `post_process'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/attachment.rb:114:in `assign'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/paperclip-4.1.1/lib/paperclip/has_attached_file.rb:66:in `block in define_setter'
from (irb):2
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/railties-4.0.2/lib/rails/commands/console.rb:90:in `start'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/railties-4.0.2/lib/rails/commands/console.rb:9:in `start'
from /Users/AnsPoluke/.rvm/gems/ruby-2.1.0/gems/railties-4.0.2/lib/rails/commands.rb:62:in `<top (required)>'
from bin/rails:4:in `require'

任何想法为什么它与styles完美配合但与convert_options失败?

5 个答案:

答案 0 :(得分:8)

注意:尚未在工作代码上验证

似乎传入的块的参数:convert_options已经是一个实例,而不是附件(而不是样式选项,它是附件)

尝试:

convert_options: lambda { |instance| instance.decide_convert_options }

如果您提取配置数据,那么您的代码会更好看,例如:

has_attached_file :image,
  styles: lambda { |attachment| attachment.instance.image_options[:styles] }, 
  convert_options: lambda { |instance| instance.image_options[:convert_options] }


IMAGE_OPTIONS = {
  poster: {
    styles: {
      thumb: ["30x45!", :jpg],
      standard: ["185x278!", :jpg],
      expanded: ["372x559!", :jpg]
      big: ["600x900!", :jpg]
    },
    convert_options: {
      thumb: "-flop",
      standard: "-flop",
      expanded: "-flop",
      big: = "-flop"
    }
  },
  cover: {
    styles: {
      thumb: ["30x45!", :jpg],
      standard: ["300x1200!", :jpg]
    },
    convert_options: {
      thumb: "-enhance",
      standard: "-enhance"
    }
  }
}

def image_options
  IMAGE_OPTIONS[self.image_class]
end

我希望有帮助

更新:

看起来你的convert_options没有在这里设置: https://github.com/thoughtbot/paperclip/blob/a93dfc773b4fd649db4d1281b42a2a71b1ae72ff/lib/paperclip/style.rb#L55

似乎他们建议传递带有样式的convert_options,例如此规范:https://github.com/thoughtbot/paperclip/blob/263a498195d47563a6227be18cf4463c4c6e7903/spec/paperclip/style_spec.rb#L41

你可以尝试一下吗?所以完全删除convert_options,并在配置中返回哈希,如:

IMAGE_OPTIONS = {
      poster: {
        styles: {
          thumb: {
            geometry: "30x45!",
            format: :jpg,
            convert_options: '-flop',
          },
          standard: {...}
          expanded: {...}
          big: {...}
        }
      },
      cover: {
        styles: {...}

答案 1 :(得分:2)

应用于所有人,因为你还在做什么?

:convert_options => {:all => "-flop"}

如果你没有考虑创建Paperclip Processor

答案 2 :(得分:2)

批准的答案不起作用。它可以在评论中阅读,作者承认它尚未在代码中进行测试。

此代码 工作:

has_attached_file :image,
                  :styles => lambda { |attachment|

                    thumb_convert_options = case attachment.instance.image_class
                      when "poster"
                        "-flop"
                      when "cover"
                        "-enhance"
                    end

                    {
                      thumb: {
                        convert_options: thumb_convert_options
                      }
                    }
                  }

正确的方法是在convert_options lambda中设置styles;将它作为单独的lambda不起作用,至少对于Paperclip 4.1及更高版本而言。

为了在一个地方保留我的答案,我将所有代码内联并省略了thumb旁边的所有样式。显然要实现这一点,你应该保留方法decide_convert_options

答案 3 :(得分:1)

convert_options添加到styles中。下面是一个通用rails图像模型的示例,它包含两个样式和相应的布尔值来启用这些样式。

# == Schema Information
#
# Table name: images
#
#  id                 :integer          not null, primary key
#  image_file_name    :string(255)
#  image_content_type :string(255)
#  image_file_size    :integer
#  hero_style         :boolean 
#  thumb_style        :boolean 
#  image_updated_at   :datetime
#  created_at         :datetime         not null
#  updated_at         :datetime         not null
#

class Image < ActiveRecord::Base

  # These are the postprocessing options. 
  # The boolean <stylename>_style? attributes controls which styles are created. 

  STYLES = {
    hero: {geometry: "2500x800#", convert_options: "-quality 75 -strip", source_file_options: ""},
    thumb: {geometry: "312x100#", convert_options: "-quality 75 -strip", source_file_options: ""}  
  }

  has_attached_file :image,
    styles: 
      lambda { |file|
        r = {}
        STYLES.keys.each do |stylename|
          r[stylename] = STYLES[stylename] if file.instance.method("%s_style?" % stylename).call
        end
        return r
      }

  validates_attachment :image, :presence => true,
  content_type: { content_type: ["image/jpeg", "image/png"] },
  file_name: {matches: [/png\Z/, /jpe?g\Z/]}



end

答案 4 :(得分:1)

您还可以在样式中指定convert_options

class Image < ActiveRecord::Base
  has_attached_file :image, styles: -> (attachment) { attachment.instance.paperclip_styles }

  private

  def image_ratio
    # logic to define the image ratio
  end

  def paperclip_styles
    vitrina_geometry = image_ratio > 1.2 ? '268x156>' : '268x156^'
    vitrina_convert_options = if image_ratio > 1.2
      "-quality 75 -gravity center -crop '268x156+0+0'"
    else
      "-quality 75 -strip -gravity center -background '#FFFFFF' -extent 268x156"
    end

    {
      medium: { 
        geometry: '500x500>',
        convert_options: '-quality 75 -strip'
      },
      thumb: {
        geometry: '256x148>',
        convert_options: '-quality 75 -strip'
      },
      small: {
        geometry: '120x120>',
        convert_options: '-quality 75 -strip'
      },
      course_thumb: {
        geometry: '395x220^',
        convert_options: '-quality 75 -gravity center -crop \'395x220+0+0\''
      },
      :vitrina => {
        geometry: vitrina_geometry,
        convert_options: vitrina_convert_options
      }
    }
  end
end