I am trying to abstract some of the logic required for cropping images into a module so that its not messing up my models. The code is based on http://railscasts.com/episodes/182-cropping-images
module CroppableImage
def croppable_image(*image_names)
image_names.each do |image_name|
define_method "#{image_name}_sizes" do
{ :cropped => read_attribute("#{image_name}_size").to_s, :large => "800x800>" }
end
define_method "#{image_name}_geometry" do |style|
style ||= :original
@geometry ||= {}
@geometry[style] ||= Paperclip::Geometry.from_file(eval "#{image_name}.path(style)")
end
define_method "#{image_name}_aspect_ratio" do
width, height = read_attribute("#{image_name}_size").split("x")
width.to_f / height.to_f
end
private
define_method "reprocess_#{image_name}" do
eval "#{image_name}.reprocess!"
end
end
end
end
To include this into my model it seems that I have to use extend. I thought extend was for including class methods. I am from a java background - I thought using extend basically created static method on the class.
class Website < ActiveRecord::Base
extend CroppableImage
croppable_image :logo, :footer_image
-- this works
It seems then that what I am really wanting is to create instance methods.
class Website < ActiveRecord::Base
include CroppableImage
croppable_image :logo, :footer_image
-- This throws the error "undefined method `croppable_image' for #"
Can anyone please explain whats going on and if I should be using include or extend in this case. Thanks guys
extend M
internally is similar to class << self; include M; end
class << self; include M; end
class << self; include M; end
- extend
includes module into singleton class of an object (and makes instance methods of the module to be a singleton methods of a class you extend).
In your case you call croppable_image
in the context of a class definition and thus croppable_image
should be an instance method of a Class
class or a singleton method of Website
class.
This is why you should extend Website
class with a module CroppableImage
by using extend CroppableImage - it adds instance method croppable_image
as a singleton method of Website
class.
you can use both logic together. Ruby has callbacks for extend and include Example of using included callback
module CroppableImage
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def bar
puts 'class method'
end
end
def foo
puts 'instance method'
end
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.