App Model "Image" conflicts with RMagick "Image"

Hello,

In the following code from my RoR app:

**** Code ***
require ‘RMagick’
include Magick

class ThumbnailController < ApplicationController
def thumbnail
image = Image.find(params[:id])

thumbnail = Magick::Image.new("#{RAILS_ROOT}image.path")
thumbnail.change_geometry("#{params[:max_width]}x#{params[:max_height]}")

send_data thumbnail.to_blob,
  :type => image.content_type,
  :disposition => 'inline',
  :filename => "#{images.id} Thumbnail.#{image.extension}"

end
end
*** End Code ***

Where Image is a model I have created for my app, I get the error:

“undefined method `find’ for Magick::Image:Class”

because apparently Magick::Image has supplanted my Image model as the
top-level symbol (and clearly ‘find’ isn’t a defined method for it.) I
am looking for suggestions to solve this conflict. Below are some of my
thoughts; please comment on the applicability of
them to a RoR application.

(1) Rename my model, perhaps with some prefix: MyImage. This seems
unacceptable because idiomatic Rails applications name their models
models clearly after the concept they encapsulate.

(2) Put my model in a namespace: Module::Image. This solution is
recommended against on the web for somewhat vague reasons. It also
seems awkward to have to type the Module name before the model each
time.

Neither of these solutions seems ideal. Some other possibilities
(about which I know little) are:

(3) Somehow explicitly refer to my Image model using some foolproof
reference system. Perhaps some Module or default namespace that a
Rails application’s models are all in? Basically: is there any way at
all to refer to my Image model without relying upon it to be in Ruby’s
top-level symbol table?

(4) Somehow refer to the RMagick::Image model without importing the
model’s name into the top-level symbol table. Is this possible?

Thank you.

Rename the model

Picture
Graphic
Photo

I ran into this too. It’s just easier not to fight it.

Hello Carl,

2006/10/27, Carl [email protected]:

require ‘RMagick’
include Magick

“Don’t do that” ! You’re including the Magick methods into the global
namespace. That’s why your Image model can’t be picked up. It is
being shadowed by RMagick’s Image class.

Looking at your code, you are already using properly namespaced
RMagick constants / classes.

Hope that helps !

François Beausoleil
http://blog.teksol.info/
http://piston.rubyforge.org/

François Beausoleil wrote:

Hello Carl,

2006/10/27, Carl [email protected]:

require ‘RMagick’
include Magick

“Don’t do that” ! You’re including the Magick methods into the global
namespace. That’s why your Image model can’t be picked up. It is
being shadowed by RMagick’s Image class.

Looking at your code, you are already using properly namespaced
RMagick constants / classes.

Hope that helps !

François Beausoleil
http://blog.teksol.info/
http://piston.rubyforge.org/

You dont need to “include RMagick” at all. The problem is solved by
simply accessing the RMagick Image model by “RMagick::Image” and your
own with “Image”, whic it looks liek your already doing.

remove the “include RMagick” and you should be fine.

François Beausoleil wrote:

Hello Carl,

2006/10/27, Carl [email protected]:

require ‘RMagick’
include Magick

“Don’t do that” ! You’re including the Magick methods into the global
namespace. That’s why your Image model can’t be picked up. It is
being shadowed by RMagick’s Image class.

Looking at your code, you are already using properly namespaced
RMagick constants / classes.

Hope that helps !

François Beausoleil
http://blog.teksol.info/
http://piston.rubyforge.org/

Hi Francois,

Thank you for your suggestion. It worked! I still needed the require
statement. There were also some errors in my previous code. The
working version of the code is below.

class ThumbnailController < ApplicationController
def thumbnail
require ‘RMagick’

image = Image.find(params[:id])

#read returns an array of all images found in the file (e.g. gif and

psd have multiple images in a single file
thumbnails = Magick::Image.read(“#{RAILS_ROOT}/public#{image.path}”)
#just assume that we can take the first of the images (for jpg, png,
etc.)
thumbnail = thumbnails[0]
thumbnail.change_geometry(“#{params[:max_width]}x#{params[:max_height]}”)
{|cols, rows, img|
thumbnail.resize!(cols, rows)
}

send_data thumbnail.to_blob, :type => image.content_type,

:disposition => ‘inline’, :filename => “#{image.id}
Thumbnail.#{image.extension}”
end
end

Carl wrote:

(3) Somehow explicitly refer to my Image model using some foolproof
reference system. Perhaps some Module or default namespace that a
Rails application’s models are all in? Basically: is there any way at
all to refer to my Image model without relying upon it to be in Ruby’s
top-level symbol table?

Seems like I ran into something like this before. Will

image = ::Image.find(params[:id])

work? Seems like it should.

Eric

Alex W. wrote:

François Beausoleil wrote:

Hello Carl,

2006/10/27, Carl [email protected]:

require ‘RMagick’
include Magick

“Don’t do that” ! You’re including the Magick methods into the global
namespace. That’s why your Image model can’t be picked up. It is
being shadowed by RMagick’s Image class.

Looking at your code, you are already using properly namespaced
RMagick constants / classes.

Hope that helps !

François Beausoleil
http://blog.teksol.info/
http://piston.rubyforge.org/

You dont need to “include RMagick” at all. The problem is solved by
simply accessing the RMagick Image model by “RMagick::Image” and your
own with “Image”, whic it looks liek your already doing.

remove the “include RMagick” and you should be fine.

Hi Alex,

Thank you for your suggestion. If I remove the require and include
statements entirely, I get the error:

uninitialized constant ThumbnailController::Magick

I am using the Locomotive environment on Mac OS X. Perhaps in another
environment it would work.

Eric A. wrote:

Carl wrote:

(3) Somehow explicitly refer to my Image model using some foolproof
reference system. Perhaps some Module or default namespace that a
Rails application’s models are all in? Basically: is there any way at
all to refer to my Image model without relying upon it to be in Ruby’s
top-level symbol table?

Seems like I ran into something like this before. Will

image = ::Image.find(params[:id])

work? Seems like it should.

Eric

Hi Eric,

Thanks for your suggestion. Using “::” solved the problem. A version
of the code using that solution is:

class ThumbnailController < ApplicationController
require ‘RMagick’
include Magick

def thumbnail

image = ::Image.find(params[:id])

#read returns an array of all images found in the file (e.g. gif and

psd have multiple images in a single file
thumbnails = Magick::Image.read("#{RAILS_ROOT}/public#{image.path}")
#just assume that we can take the first of the images (for jpg, png,
etc.)
thumbnail = thumbnails[0]
thumbnail.change_geometry("#{params[:max_width]}x#{params[:max_height]}")
{|cols, rows, img|
thumbnail.resize!(cols, rows)
}

send_data thumbnail.to_blob, :type => image.content_type,

:disposition => ‘inline’, :filename => “#{image.id}
Thumbnail.#{image.extension}”
end
end