Предоставление переменной строки в модель для изменения размера Paperclip Imagemagik

#ruby-on-rails #paperclip

#ruby-on-rails #скрепка

Вопрос:

Я использую paperclip для загрузки некоторых изображений, размер которых изменяется. Один из которых я хочу обрезать одним из пяти способов… В любом случае, я выяснил, как должны выглядеть строки для обрезки, изменив их вручную, но теперь мне нужно сделать это динамичным, чтобы paperclip мог обрезать в зависимости от того, что хочет пользователь…

Проблема в том, что я получаю

 undefined local variable or method `params' for #<Class:0x00000105b228d8>
  

Я уверен, что это потому, что я пытаюсь согнуть рельсы по своей воле. В любом случае, я думаю, довольно ясно, что я пытаюсь сделать… Просто укажите переменную crop_geometry_thumb в convert_options… Где я должен на самом деле поместить эту логику, чтобы моя модель могла ее найти?

 class Asset < ActiveRecord::Base
   if  params[:crop_geometry] == "bottom"
     crop_geometry_thumb = "-crop 200x100 0 100 -scale 100x100"
   elsif  params[:crop_geometry] == "top"
     crop_geometry_thumb = "-crop 200x100 0 0 -scale 100x100"
   elsif  params[:crop_geometry] == "left"
     crop_geometry_thumb = "-crop 100x200 0 100 -scale 100x100"
   elsif  params[:crop_geometry] == "right"
     crop_geometry_thumb = "-crop 100x200 100 0 -scale 100x100"
   else
     crop_geometry_thumb = "-scale 100x100"
   end

  belongs_to :piece
  has_attached_file :asset, :styles => {
    :large => ['700x700', :jpg], 
    :medium => ['300x300>', :jpg], 
    :thumb => ["200x200>", :jpg]},
    :convert_options => {:thumb => crop_geometry_thumb}, ### supply a string from above... FAIL :(
    :path => ":id/:style/:filename",
    :storage => :s3,
    :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
    :s3_permissions => :private,
    :url => ':s3_domain_url'
end
  

Ответ №1:

Итак, непосредственная проблема заключается в том, что параметры запроса (т. Е. params[:crop_geometry] ) недоступны для вашей модели, только для вашего контроллера views.

В некоторых случаях (хотя это никогда не бывает хорошей идеей) вы можете обойти это правило MVC, передав параметры вашей модели в качестве аргумента для метода:

 class FoosController < ApplicationController

  def action
     Foo.some_method(params)
  end
end

class Foo < ActiveRecord::Base

  some_method(params)
     puts params[:crop_geometry]
  end
end
  

Вместо этого я бы рекомендовал передать эту информацию о параметрах в переменную экземпляра, определенную в модели, и поместить условную логику в пользовательский метод установки, например:

 class Asset < ActiveRecord::Base
  attr_reader :crop_geometry

  def crop_geometry=(crop_type)
    if  crop_type == "bottom"
     crop_string = "-crop 200x100 0 100 -scale 100x100"
    elsif  crop_type == "top"
      crop_geometry_thumb = "-crop 200x100 0 0 -scale 100x100"
    elsif  crop_type == "left"
      crop_geometry_thumb = "-crop 100x200 0 100 -scale 100x100"
    elsif  crop_type == "right"
      crop_geometry_thumb = "-crop 100x200 100 0 -scale 100x100"
    else
      crop_geometry_thumb = "-scale 100x100"
    end
    @crop_geometry = crop_geometry_thumb
  end
end
  

Обратите внимание, что вам придется изменить свою форму, чтобы она присваивала ‘top’, ‘bottom’ или что-либо еще параметрам [:asset][:crop_geometry] .

Теперь, чтобы динамически задать crop_geometry, вам нужно будет использовать лямбда-выражение в конфигурации has_attached_file — таким образом, оно будет оцениваться при каждом обращении к конфигурации, а не только при начальной загрузке модели. Поехали:

 has_attached_file :asset, :styles => lambda {|attachment|
    :large => ['700x700', :jpg], 
    :medium => ['300x300>', :jpg], 
    :thumb => ["200x200>", :jpg]},
    :convert_options => {:thumb => attachment.instance.crop_geometry},
    :path => ":id/:style/:filename",
    ...
}
  

Получил эту последнюю часть из https://github.com/thoughtbot/paperclip (найдите «Динамическая конфигурация»).

Комментарии:

1. Спасибо, Сэм! Сейчас я играю с этим и смотрю, смогу ли я заставить его работать. Я должен сказать, что я очень удивлен, увидев здесь кого-то, кого я действительно знаю лично.

2. да, я только заметил, что вы наполовину ответили на вопрос. Мир тесен!

3. Итак, я потратил на это несколько часов с тех пор, как мы в последний раз публиковали здесь. Причина, по которой я не пометил это как ответ, заключается в том, что он все еще не работает для меня. Когда я пытаюсь запустить код с лямбда-символом на месте, я получаю «экземпляр неопределенного метода для : all:Symbol». Что приводит меня к вопросу, что означает слово «экземпляр» в этом лямбда-выражении? Я вижу это в примерах Paperclip, но для меня это все еще не имеет смысла :/

4. Эй, так что не совсем уверен, что такое метод «instance» — это специфично для paperclip. Я предполагаю, что paperclip уступает лямбде, которую вы передаете с помощью класса attachment, который имеет метод «instance», который возвращает конкретный экземпляр, с которым вы имеете дело по данному запросу. В любом случае, проблема, похоже, в том, что paperclip передает «: all» вместо ожидаемого объекта. Обновил приведенный выше код, я думаю, теперь он может работать!

5. Я тоже получаю ошибку «экземпляр неопределенного метода для : all: Symbol». У кого-нибудь это работает?