#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». У кого-нибудь это работает?