如何在不继承ActiveRecord :: Base的类中使用Paperclip gem for Rails?

时间:2011-12-27 18:51:17

标签: ruby-on-rails paperclip activemodel

似乎有些人通过执行以下操作让Paperclip在常规ruby类上工作:

require "paperclip"

Class Person
   include Paperclip
   has_attached_file :avatar,{}
end

参见here 即使使用主要的Paperclip仓库,这对我也不起作用:

$ bundle exec rails c
>> Rails.version
=> "3.1.3"
>> require 'paperclip'
=> false
>> class Monkey
>> include Paperclip
>> has_attached_file :avatar,{}
>> end
NoMethodError: undefined method `has_attached_file' for Monkey:Class

有没有人得到这个工作,并可能提供一个可能出错的线索?

谢谢!

2 个答案:

答案 0 :(得分:2)

Paperclip非常明确地用于AR。

另一种选择是使用载波而不是在AR之外,使用各种ORMS,或者不使用载波:

https://github.com/jnicklas/carrierwave

答案 1 :(得分:0)

我最近不得不弄清楚这一点。您需要在定义库类或模型时使用一些ActiveModel。具体来说,要使用Paperclip,您需要以下方法:save,destroy,它们的回调,to_key(用于form_for),attr_acessors用于id,当然还有* _file_name,* _file_size,* _content_type,* _updated_at用于每个附加文件。

以下课程应该为您提供所需的最低实施。这个“解决方案”使用Rails 3.2.8,Ruby 1.9.3和Paperclip 3.2.0截至2012年9月10日,尽管其他配置也可以使用。

class Importer
    extend  ActiveModel::Callbacks
    include ActiveModel::Validations

    include Paperclip::Glue

    define_model_callbacks :save
    define_model_callbacks :destroy

    validate :no_attachement_errors

    attr_accessor :id, :import_file_file_name, :import_file_file_size, :import_file_content_type, :import_file_updated_at

    has_attached_file :import_file,
                      :path => ":rails_root/public/system/:attachment/:id/:style/:filename",
                      :url  => "/system/:attachment/:id/:style/:filename"

    def initialize(args = { })
      args.each_pair do |k, v|
        self.send("#{k}=", v)
      end
      @id = self.class.next_id
    end

    def update_attributes(args = { })
      args.each_pair do |k, v|
        self.send("#{k}=", v)
      end
    end

    def save
       run_callbacks :save do
       end
    end

    def destroy
      run_callbacks :destroy do
      end
    end

    # Needed for using form_for Importer::new(), :url => ..... do
    def to_key
      [:importer]
    end

    # Need a differentiating id for each new Importer.
    def self.next_id
      @@id_counter += 1
    end

    # Initialize beginning id to something mildly unique.
    @@id_counter = Time.now.to_i

  end

文件上传的表单可能如下所示:

<%= form_for Importer.new, :url => import_nuts_path do |form| %>
   <%= form.file_field 'import_file' %>
   <%= form.submit 'Upload and Import' %>
<% end %>

并且NutsController将执行以下操作:

class NutsController < ActionController::Base
    def import
       importer = Importer.new(params[:importer])
       importer.save
    end
end

注意 ::您必须调用“保存”或不会发生任何事情。调用“destroy”将删除服务器端的文件。由于这个类不是持久的,你可能应该在控制器中完成它之后这样做,否则如果你不进行任何清理,你最终会出现文件空间泄漏。

安全提示:此“解决方案”未对new()和update_attributes()使用任何ActiveModel :: MassAssignmentSecurity,但此类并不真正需要它。你的旅费可能会改变。小心那里!

干杯,
-Dr。极性