Перемещение навесного скрепки S3 на Heroku - PullRequest
0 голосов
/ 03 августа 2011

Я пытаюсь сделать что-то очень простое, используя Heroku, Paperclip и S3 - установить привязанность одной модели к другой.

Вот пользовательское задание на грабли, которое я собрал:

task :migrate => :environment do
    @companies = Company.where("attachment_file_name IS NOT NULL")    
    @companies.each do |c|
        if c.attachments.where("attachment_file_name = ?", c.attachment_file_name).blank?
        # i.e. if there are no instances of Attachment that match c.attachment
            a = Attachment.new( :company_id => c.id, :name => "Default" )
            a.attachment = c.attachment
            a.save
        end
    end
end

Итак, я пытаюсь переместить Company.attachment в новый экземпляр новой модели Attachment. На моем локальном сервере разработки все работает прекрасно.

После нажатия на Heroku я получаю следующую ошибку, указывающую на строку a.attachment = c.attachment.

The specified key does not exist.

Я пытаюсь выполнить операцию вручную для компании, которая имеет вложение в консоли heroku, и получаю:

TypeError: can't convert nil into String
/app/.bundle/gems/ruby/1.8/gems/paperclip-2.3.6/lib/paperclip/storage/s3.rb:131:in `extname'
/app/.bundle/gems/ruby/1.8/gems/paperclip-2.3.6/lib/paperclip/storage/s3.rb:131:in `to_file'
/app/.bundle/gems/ruby/1.8/gems/paperclip-2.3.6/lib/paperclip/attachment.rb:81:in `assign'
/app/vendor/plugins/paperclip/lib/paperclip.rb:245:in `attachment='

Вы знаете, что здесь происходит?


Я только что попробовал c.attachment = c.attachment. Та же ошибка !!!

Ответы [ 3 ]

0 голосов
/ 30 августа 2011

Рассматривали ли вы возможность изменения модели скрепки для принятия URL-адреса в качестве вложения?Таким образом, вы можете перенести свои вложения на новую модель и не радикально изменить механизм хранения paperclip s3.

Добавьте это к своей новой модели:

before_validation :download_remote_attachment, :if => :attachment_url_provided?

...

attr_accessor :attachment_url

  private

  def attachment_url_provided?
    !self.attachment_url.blank?
  end

  def download_remote_attachment
    self.file = do_download_remote_image
  end

  def do_download_remote_attachment
    io = open(attachment_url)
    def io.original_filename; base_uri.path.split('/').last; end
    io.original_filename.blank? ? nil : io
  rescue
  end   

Затем, чтобы создать новый объект вложения, передайте ему параметр: attachment_url, и он загрузит его, повторно обработает и сохранит как вложение для новой модели.Единственным недостатком этого является то, что вложение будет храниться дважды на S3.В зависимости от требований вашего приложения, это может быть полезно

0 голосов
/ 31 августа 2011

Еще один длинный снимок в темноте, с точки зрения "почему он работает с db разработки, а не с производством db".Есть ли шанс, что attachment станет доступным через отношения has_many :through?Прочитал этот тип причудливой ошибки может произойти с MySQL, если к таблице соединения добавлен первичный ключ.Будет работать с sqLite3, хотя.Итак, когда вы идете в производство, ошибка видна.Просто мысль.

0 голосов
/ 03 августа 2011

Похоже, c.attachment_file_name приближается, ноль, и скрепка не знает, что с этим делать.Я не уверен, почему это ноль, но чтобы обойти это, вы можете просто проверить, если это ноль, и пропустить его, если оно:

if c.attachment_file_name
    if c.attachments.where("attachment_file_name = ?", c.attachment_file_name).blank?
        # i.e. if there are no instances of Attachment that match c.attachment
        a = Attachment.new( :company_id => c.id, :name => "Default" )
        a.attachment = c.attachment
        a.save
    end
end
...