FlexImage update: now multi-class safe
April 12th, 2007
This information is now old. A new version of the plugin can be found here with lots of instructions and examples.
NOTE: Before you update your plugin, install the dsl_accessor gem.
gem install dsl_accessor
Sorry it took so long guys, but FlexImage now has full support for multiple classes with different settings. The problem with class variables (the @@foo variety) is that if they point to the exact same object in all classes that inherit from the class it was defined in. For example:
class A
@@foo = 'A'
def self.foo
@@foo
end
end
A.foo #=> "A"
class B < A
@@foo = 'B'
end
A.foo #=> "B"
B.foo #=> "B"
So changing @@foo in the class B, changes it in class A, as well as it’s siblings.
The solution
There is a great gem out there class dsl_accessor. It provides a way to declare inheritance safe class level variables through an elegant API. I have transitioned all class level variables in FlexImage from the old @@foo style to the new and sexy accessors.
This also means some syntactic sugar (although, still backwards compatible). Where before you had to declare these values like this:
self.file_store = 'path/to/master_images'
Now you can do any of the following:
file_store 'path/to/master_images'
self.file_store 'path/to/master_images'
self.file_store = 'path/to/master_images'
And rest assured that all attributes are safe from their parent and siblings.
Found a bug?
As always, simply post here with any problems you may have and I will assist as best I can.
June 28th, 2007 at 11:05 PM
Thanks for the update!
Found just one small renaming issue in controller.rb:
--- vendor/plugins/flex_image/lib/flex_image/controller.rb (revision 175) +++ vendor/plugins/flex_image/lib/flex_image/controller.rb (working copy) @@ -110,7 +110,7 @@ # def render_flex_image(img) img.to_jpg! - send_data(img[img.class.data_field], :type => 'image/jpeg', :disposition => 'inline') + send_data(img[img.class.binary_column], :type => 'image/jpeg', :disposition => 'inline') GC.start endJune 28th, 2007 at 11:05 PM
Committed.
Thanks for the patch, Dustin!
June 28th, 2007 at 11:05 PM
Seems to do the trick, thanks for fixing that.
June 28th, 2007 at 11:05 PM
Does this make Single Table Inheritance work now? That is, can I have my base class for the Single Table Inheritance inherit from FlexImage rather than ActiveRecord::Base?
June 28th, 2007 at 11:05 PM
Sorry Michael, I just did a search and read your original post for the first time. Somehow I missed it.
Well this is a trickier issue. Mainly because there are a few methods that rely on
superto default toActiveRecord::Basefor execution. Thesupermethod is insanely awesome, and it only available for inherited methods, not mized in ones. To do the same with a mixin would require some messy method aliasing that would give me a headache.Also, my personal feeling is that inheritance is that best way to add functionality to a class. Especially for functionality that is only supposed to work with a single pre-defined class. It’s just cleaner and neater.
That said, I don’t see any reason why that would be impossible to do with a mixin, but I don’t think that is where this plugin will go. You are welcome to convert it on your own, however.
These are the limitations of Ruby being single inheritance, and STI being implemented via class inheritance. Sometimes you can’t have both.
If you come up with a solution, post it here. I would love to see it.
June 28th, 2007 at 11:05 PM
You could use Rails’ built-in
class_interitable_*methods to get the same effect as withdsl_accessor.June 28th, 2007 at 11:05 PM
Alex.
No worries… I just stored the image in a different table and use your insanely great plugin for that :-).
June 28th, 2007 at 11:05 PM
Tim Lucas: Yes, I could. In fact,
dsl_accessordoes use it. But it also allows easy creation of very clean way to set those attributes:before:
after
June 28th, 2007 at 11:05 PM
Rails throws an exception when I try to view an image backed by the filesystem when the image file is missing for whatever reason. I would think the correct thing to do would be to log an error and return a 404 to the user.
June 28th, 2007 at 11:05 PM
Back again… with another patch. Is there some sort of other way I can let you know about that sort of thing?
The patch adds a rmagick_process! method that lets you get access to the RMagick image object to do fancier operations on it. It also changes most of the other resize! etc methods to use it.
I wrote it before I discovered that the trim! method I wanted already existed :)
Interested?
June 28th, 2007 at 11:05 PM
donald: This is why I usually advocate having a model dedicated to images and it being associated to other models. If there is no image for a dedicated image model, then you really are in an exceptional situation and should be raised as such. You should be able to check yourself with something like:
Simon Russel: Sounds interesting. There is a private method call
rmagick_imagewhich actually just returns the rawRMagick::Imageobject. It’s used internally for processing. If what you have done gives a better solution, I would love to see it. Send it to the email the README.June 28th, 2007 at 11:05 PM
FYI: dsl_accessor is now REQUIRED if you’re going to use FlexImage—if you install FlexImage and don’t have dsl_accessor and restart your server you get an error msg. I think.
June 28th, 2007 at 11:05 PM
Yes, Erik. Sorry if that wasn’t clear enough. Although the error that you get should be clear. It specifically tells you the gem you need isn’t there and even tells you what to type to install it.
June 28th, 2007 at 11:05 PM
First of all thank you for this great plugin!
I have an image upload service running very well, but now i want to support batch upload via zip files.
First of all i extract all Files to a temporary folder and want to add each Image via FlexImage to my database. Also of interest will be, that i’m using rubyzip. So, my files are all extract to the filesystem.
Example:
In this case I’m getting
undefined method `size’ for #<file:0x5fbe7f8>
How to add images via FlexImage through the filesystem?
Thank you in advance!
Matze
June 28th, 2007 at 11:05 PM
Hi, I have a little problem(!) that makes me work on for 3 weeks :(
On Dreamhost i can’t make my flex_image work. Only the page with the plugin gives “FlexImage… error” when the plugin isn’t in plugins dir. When i install plugin rails gives application error and does not show page.
Also after i script/server it works but gives;
WARNING :: FlexImage :: Your version of RMagick does not support the “crop_resized!” method. Upgrade RMagick to get this functionality.
Here’s Rmagick, /usr/lib/ruby/gems/1.8/gems/rmagick-1.14.1
And imagemagick version; ImageMagick 6.2.4
Please help!!! I have to finish the project!
June 28th, 2007 at 11:05 PM
REST Url question?
I am not sure where to post this so I ll go ahead as comment over here.
I have the following:
class myClass < ActiveRecord::Base has_one :logo, :as => :logoable end
class Logo < FlexImage::Model belongs_to :logoable, :polymorphic => true end
in myClassController I have: flex_image :action => :logo, :class => Logo
To access the logo I need the following URL: myClass\logo\:the_id_in_the_many_2_many_table
Would it not be better to have something of this sort: myClass\:id_of_my_class\logo
I was even thinking: myClass\:id_of_my_class\logo_:size
I am posting before I get into the routing and try to write a solution myself. Has anybody come across this? any solutions?
Regards, Carl
June 28th, 2007 at 11:05 PM
Hi,
I have used fleximage in the past without any problem – however, i have just started a new project, installed the dll_accesor, the flex_image plugin and created a flex image through the generator ruby script/generate flex_image Photo
when I do a rake i get the following errors – any thoughts or help on this would be greatly appreciated.
F:\Software\Rails\cmr>rake migrate db—trace (in F:/Software/Rails/cmr)June 28th, 2007 at 11:05 PM
Sorry it’s taken me so long to get you guys. Let see how I can help.
Matze: Ruby’s uploaded file classes are different from the local files classes. I solve this in my tests by using a little
MockFileclass. I makes a local file look like an uploaded file to FlexImage. Try something like this:require 'vendor/plugins/flex_image/test/mockfile' file = MockFile.new('/path/to/local/file/jpg') @image = MyImage.new(:data => file)d3s: Your gonna have to talk to dreamhost about that. RMagick must be installed as a gem, so it has to be handled by your shared host. And without a more specific error message besides “FlexImage … error” I can;t really help you there either.
Carl: You can do this easily.
#routes.rb map.resources :my_class, :member => {:logo => :get} #environment.rb Mime::Type.register "image/jpg", :jpg formatted_logo_my_class_path(123, :jpg) #=> /my_classes/123/logo.jpgseamus: Sounds like your RMagick install got borked somehow. try this in irb:
require 'rubygems' require 'RMagick' Magick::Image.read('/path/to/local/img.jpg').firstIf it works, RMagick should be working properly on your machine, if not you may need to reinstall.
June 28th, 2007 at 11:05 PM
Hi,
I had them re-install RMagick and i get through the code you suggested above.
I now run into a problem when I install the dsl_accessor and flex_image. I get a “Rails application failed to start properly” error message. Without having done the flex-image install i don’t get that. The specific error is:
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require’: no such file to load
- dsl_accessor (MissingSourceFile) from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require’ from /usr/lib/ruby/gems/1.8/gems/activesupporti am running on Bluehost if that means anything – i don’t have any problem on my local machine (windows) and I see the dsl_Accessor listed when I list gems on the server.
June 28th, 2007 at 11:05 PM
i think i have figured the previous post out – I did not have the ENV[‘GEM_PATH’] set up in my environment.rb file
thanks