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

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

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

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

person counterbeing    schedule 19.10.2011    source источник


Ответы (1)


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

В некоторых случаях (хотя это никогда не бывает хорошей идеей) вы можете обойти это правило 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

Обратите внимание, что вам придется изменить свою форму, чтобы она назначала «верх», «низ» или что-то еще для params[: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 (ищите "Динамическая конфигурация" ).

person sam1vp    schedule 19.10.2011
comment
Спасибо Сэм! Я играю с ним сейчас и смотрю, смогу ли я заставить его работать. Я должен сказать, что очень удивлен, увидев здесь кого-то, кого я действительно знаю лично. - person counterbeing; 20.10.2011
comment
да, я только заметил, что вы были на полпути к ответу на вопрос. Маленький мир! - person sam1vp; 21.10.2011
comment
Итак, я потратил на это несколько часов с тех пор, как мы в последний раз писали здесь. Причина, по которой я не отметил это как ответ, заключается в том, что он все еще не работает для меня. Когда я пытаюсь запустить код с лямбдой на месте, я получаю неопределенный метод `экземпляр' для :all:Symbol. Что приводит меня к вопросу, что означает слово экземпляра в этой лямбде? Я вижу это в примерах Paperclip, но для меня это все еще не имеет смысла :/ - person counterbeing; 08.11.2011
comment
Эй, так что не совсем уверен, что такое метод экземпляра - он специфичен для скрепки. Я предполагаю, что скрепка уступает лямбде, которую вы передаете с классом вложения, который имеет метод экземпляра, который возвращает конкретный экземпляр, с которым вы имеете дело по заданному запросу. В любом случае проблема заключается в том, что скрепка проходит через :all вместо объекта, который вы ожидаете. Обновил приведенный выше код, думаю, теперь он может работать! - person sam1vp; 10.11.2011
comment
В конце концов я решил отказаться от всего этого подхода в пользу чего-то более гибкого. Во всяком случае, это похоже на ответ, поэтому я отмечаю его как таковой. Спасибо еще раз! - person counterbeing; 18.12.2011
comment
Я также получаю неопределенный метод «экземпляр» для: all:Symbol error. У кого-нибудь это работает? - person digitalWestie; 28.03.2012
comment
У меня была аналогичная проблема. Вместо attachment.instance.crop_geometry мне пришлось использовать attachment.crop_geometry - person Sebastian; 10.09.2014