0

ペーパークリップを使用して複数の添付ファイルをアップロードし、それらを透かしで処理するのに非常に問題があります。

広告と写真の 2 つのモデルがあります。広告は has_many :photos であり、写真は belongs_to :ad です。

/models/ad.rb でより正確に言うと、次のものがあります。

class Ad < ActiveRecord::Base

  has_many :photos, :dependent => :destroy
  accepts_nested_attributes_for :photos, :allow_destroy => true  
end

私の photo.rb ファイルは次のようになります。

class Photo < ActiveRecord::Base

belongs_to :ad

has_attached_file :data,
:styles => {
  :thumb => "100x100#",
  :first => {
    :processors => [:watermark],
    :geometry => '300x250#',
    :watermark_path => ':rails_root/public/images/watermark.png',
    :position => 'SouthEast' },
  :large => {
    :processors => [:watermark],
    :geometry => '640x480#',
    :watermark_path => ':rails_root/public/images/watermark.png',
    :position => 'SouthEast' }
}
end

私の見解では、これを使用してファイルフィールドを追加します

<% f.fields_for :photos do |p| %>

  <%= p.label :data, 'Poza:' %> <%= p.file_field :data %>

<% end %>

私のコントローラーでは、編集アクション4.times {@ad.photos.build}でファイルフィールドを生成するために使用します。

次のように、通常の has_attached_file 宣言を使用すると、透かしプロセッサを使用しない場合、すべて正常に機能します。

has_attached_file :data,
:styles => {
  :thumb => "100x100#",
  :first => '300x250#',
  :large => '640x480#'
}

しかし、透かしプロセッサを使用すると、常に次のエラーが発生します。

 NoMethodError in PublicController#update_ad

 You have a nil object when you didn't expect it!
 You might have expected an instance of ActiveRecord::Base.
 The error occurred while evaluating nil.[]
  ..............................
 /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/nested_attributes.rb:350:in `assign_nested_attributes_for_collection_association'
 /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/nested_attributes.rb:345:in `each'
 /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/nested_attributes.rb:345:in `assign_nested_attributes_for_collection_association'
 /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/nested_attributes.rb:243:in `photos_attributes='
 /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2746:in `send'
 /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2746:in `attributes='
 /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2742:in `each'
 /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2742:in `attributes='
 /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2628:in `update_attributes'
 /home/alexg/Sites/vandmasina/app/controllers/public_controller.rb:217
 /home/alexg/Sites/vandmasina/app/controllers/public_controller.rb:216:in `update_ad'

私が言える限り、パラメーターは問題ありません

 Parameters:

 {"commit"=>"Salveaza modificarile",
  "ad"=>{"price"=>"6000",
  "oras"=>"9",
  "photos_attributes"=>{"0"=>{"data"=>#<File:/tmp/RackMultipart20100928-5130-b42noe-0>},
  "1"=>{"data"=>#<File:/tmp/RackMultipart20100928-5130-r0ukcr-0>},
  "2"=>{"data"=>#<File:/tmp/RackMultipart20100928-5130-mb23ei-0>},
  "3"=>{"data"=>#<File:/tmp/RackMultipart20100928-5130-1bpkm3b-0>}},

透かしプロセッサ /lib/paperclip_processors/watermark.rb は次のようになります。

  module Paperclip
class Watermark < Processor

class InstanceNotGiven < ArgumentError; 
end

def initialize(file, options = {},attachment = nil)
  super
  @file = file
  @current_format = File.extname(@file.path)
  @basename = File.basename(@file.path, @current_format)
  @watermark = ':rails_root/public/images/watermark.png'
  @current_geometry = Geometry.from_file file # This is pretty slow
  @watermark_geometry = watermark_dimensions
end

def watermark_dimensions
  return @watermark_dimensions if @watermark_dimensions
  @watermark_dimensions = Geometry.from_file @watermark
end

def make
  dst = Tempfile.new([@basename, @format].compact.join("."))
  watermark = " \\( #{@watermark} -extract #{@current_geometry.width.to_i}x#{@current_geometry.height.to_i}+#{@watermark_geometry.height.to_i /
                2}+#{@watermark_geometry.width.to_i / 2} \\) "
  command = "-gravity center " + watermark + File.expand_path(@file.path) + " " +File.expand_path(dst.path)

  begin
    success = Paperclip.run("composite", command.gsub(/\s+/, " "))
  rescue PaperclipCommandLineError
    raise PaperclipError, "There was an error processing the watermark for #{@basename}" if @whiny_thumbnails
  end
  dst
end

end
end

複数のアタッチメントなしで、通常のアプリでプロセッサを試してみましたが、完璧に機能します。私が知る限り、nested_attributes では機能しません。

アプリは、Ruby 1.8.7 と paperclip 2.3.11 を備えた Rails 2.3.5 です。

私は今2日間これを理解しようとしてきたので、あなたが何か助けを提供できるなら、それは大いに感謝されます:)

4

3 に答える 3

1

Rails 3 と paperclip > 2.3.3 を使用している場合は、https://gist.github.com/843418ソースを試してください。

于 2011-10-06T21:23:52.360 に答える
0

ああ、それは難しいものでした!

コードにエラーがほとんどなく、ネストされたモデルに関連するエラーはありません。私の説明は Rails 3 & Paperclip 2.3.3 です。

a) :rails_root が機能しません。この補間は url/path でのみ使用され、カスタム オプションでは使用されません。Rails.root.join("public/images...") に置き換える必要があります。

b) :watermark_path オプションを単に無視し、(初期化メソッドで) ハードコードされたパスのみを使用します。したがって、常に .../images/watermark.png に適用されるため、:styles に何を持っているかは問題ではありません。:rails_root が再び存在するため、機能しません。

c) Paperclip.run("composite", "foo bar there") にパラメーターを渡すと、実際には次のコマンドが実行されます。

composite 'foo bar there'

一重引用符を見ることができますか?そのため、複合コマンドはパラメーターを 1 つの巨大なパラメーターとして認識し、まったく理解していません。配列として渡す場合、配列全体ではなく、すべての項目が引用符で囲まれます。

したがって、透かしプロセッサの改良版は次のとおりです。

module Paperclip
  class Watermark < Processor

  class InstanceNotGiven < ArgumentError;
  end

  def initialize(file, options = {},attachment = nil)
    super
    @file = file
    @current_format = File.extname(@file.path)
    @basename = File.basename(@file.path, @current_format)
    # PAWIEN: use default value only if option is not specified
    @watermark = options[:watermark_path] || Rails.root.join('public/images/watermark.png')
    @current_geometry = Geometry.from_file file # This is pretty slow
    @watermark_geometry = watermark_dimensions
  end

  def watermark_dimensions
    return @watermark_dimensions if @watermark_dimensions
    @watermark_dimensions = Geometry.from_file @watermark
  end

  def make
    dst = Tempfile.new([@basename, @format].compact.join("."))
    dst.binmode

    begin
      # PAWIEN: change original "stringy" approach to arrayish approach
      # inspired by the thumbnail processor
      options = [
        "-gravity",
        "center",
        "#{@watermark}",
        "-extract",
        "#{@current_geometry.width.to_i}x#{@current_geometry.height.to_i}+#{@watermark_geometry.height.to_i / 2}+#{@watermark_geometry.width.to_i / 2}",
        File.expand_path(@file.path),
        File.expand_path(dst.path)
      ].flatten.compact.join(" ").strip.squeeze(" ")

      success = Paperclip.run("composite", options)
    rescue PaperclipCommandLineError
      raise PaperclipError, "There was an error processing the watermark for #{@basename}" if @whiny_thumbnails
    end
    dst
  end

  end
end

お役に立てば幸いです。

更新: github の最新の paperclip gem を使用する必要があります

gem 'paperclip', '>= 2.3.3', :git => "http://github.com/thoughtbot/paperclip.git"

このバージョンでは、#run の形式が再度変更されたため、コードを更新しました。テストアプリケーションを作成したので、実際に機能するはずであり、想定どおりに動作しています。

更新 2 : 実例を含むレポ:

git://repo.or.cz/paperclip-mass-example.git
于 2010-09-28T22:50:19.010 に答える
0

一見すると、watermark_path は "#{Rails.root}/..." のように見えますが、ここで多くのことが行われているように見えます。

また、フォームが form_for のように表示されません。{:multipart => true} があることを確認してください

于 2010-09-28T18:03:55.580 に答える