Как я могу использовать гем Paperclip для Rails в классе, который не наследуется от ActiveRecord :: Base? - PullRequest
0 голосов
/ 27 декабря 2011

Кажется, есть люди, которые заставили Paperclip работать с обычным классом ruby, выполнив что-то вроде следующего:

require "paperclip"

Class Person
   include Paperclip
   has_attached_file :avatar,{}
end

Смотрите здесь Это не работает даже для меняпри использовании основного репозитория 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 ]

2 голосов
/ 27 декабря 2011

Скрепка довольно явно для использования с AR.

Другой вариант - использовать несущую волну, которая работает довольно хорошо вне AR, с различными ORMS или без:

https://github.com/jnicklas/carrierwave

0 голосов
/ 11 сентября 2012

Мне недавно пришлось это выяснить. Вам нужно использовать некоторые элементы ActiveModel при определении вашего библиотечного класса или модели. В частности, для использования Paperclip вам понадобятся следующие методы: сохранить, уничтожить, их обратные вызовы, to_key (для использования с form_for), attr_acessors для идентификатора и, конечно, * _file_name, * _file_size, * _content_type, * _updated_at для каждого вложенного файла ,

Следующий класс должен дать вам минимальную реализацию, в которой вы нуждаетесь. Это «решение» использует Rails 3.2.8, Ruby 1.9.3 и Paperclip 3.2.0 по состоянию на 10 сентября 2012 г., хотя могут работать и другие конфигурации.

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

Примечание :: Вам нужно позвонить «сохранить», иначе ничего не произойдет. Вызов «уничтожить» удалит файл на стороне сервера. Так как этот класс не является постоянным, вам, вероятно, следует сделать это после того, как вы покончили с ним в контроллере, или вы получите утечку файлового пространства, если не выполните очистку.

Примечание по безопасности : это "решение" не использует ActiveModel :: MassAssignmentSecurity для new () и update_attributes (), но этот класс на самом деле не нуждается в этом. Ваш пробег может варьироваться. Будь осторожен!

Ура,
-Доктор. Polar

...