问题
I'm using paperclip to upload some images which get resized. One of which I want to be cropped one of five ways... Anyway, I worked out what the strings to crop should all look like, by changing them by hand, but now i need to make that dynamic so that paperclip can crop based upon what the user wants...
The problem is that I'm getting
undefined local variable or method `params' for #<Class:0x00000105b228d8>
I feel pretty sure that this is because I'm attempting to bend rails to my will. Anyway, I think it's pretty clear what I'm trying to do... Just supply the crop_geometry_thumb variable to convert_options... Where should I actually be putting this logic that my model will be able to find it?
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:
So the immediate problem is that request params (i.e. params[:crop_geometry]
) are not accessible to your model, only to your controller + views.
In some cases (though it's never really a good idea), you can get around this MVC rule by passing params to your model as an argument for a method:
class FoosController < ApplicationController
def action
Foo.some_method(params)
end
end
class Foo < ActiveRecord::Base
some_method(params)
puts params[:crop_geometry]
end
end
Instead, I'd recommend passing that param information into an instance variable defined in the model, and putting the conditional logic into a custom setter method, like so:
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
Note that you'll have to change your form so that it assigns 'top', 'bottom' or whatever to params[:asset][:crop_geometry].
Now, to dynamically set the crop_geometry, you'll need to use a lambda in the has_attached_file configuration--that way it'll be evaluated each time the configuration is accessed, not just when the model is initially loaded. Here you go:
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",
...
}
Got that last part from https://github.com/thoughtbot/paperclip (look for "Dynamic Configuration").
来源:https://stackoverflow.com/questions/7815375/supplying-a-variable-string-to-model-for-paperclip-imagemagik-resizing