使用回形针上传多个附件并使用水印处理它们时遇到了很多麻烦。
我有2个模特,广告和照片。 广告has_many:照片和照片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>}},
Watermark处理器/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。
应用程序是rails 2.3.5 with ruby 1.8.7和paperclip 2.3.11
如果你可以提供任何帮助,我会非常感激,因为我一直试图解决这个问题2天:)
答案 0 :(得分:1)
如果您使用rails 3和paperclip&gt; 2.3.3,试试https://gist.github.com/843418来源。
答案 1 :(得分:0)
从快速浏览一下,看起来watermark_path应该是“#{Rails.root} / ...”,虽然看起来你有很多事情要做。
另外,我没有在form_for中看到您的表单。确保你有{:multipart =&gt;真}
答案 2 :(得分:0)
哦,伙计,那是一个艰难的人!
您的代码中的错误很少,并且没有任何与嵌套模型相关的错误。我的解释是针对Rails 3&amp; Paperclip 2.3.3
a):rails_root的东西不起作用。此插值仅用于url / path而不用于自定义选项。所以你应该用Rails.root.join(“public / images ...”)
替换它b)您只需忽略:watermark_path选项,并且仅使用硬编码路径(在初始化方法中)。所以你的风格和风格一样无关紧要...... / images / watermark.png。 :rails_root还有东西,所以它无法工作。
c)当你将参数传递给Paperclip.run(“复合”,“foo bar there”)时,它实际上执行了这个命令:
composite 'foo bar there'
你能看到单引号吗?因此,复合命令将您的参数视为一个巨大的参数,并且根本不理解它。如果将它作为数组传递,则每个项都包含在引号中,而不是整个数组。
所以这里是水印处理器的改进版本:
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