Giles Bowkett wrote: > I've got a class which loads files and turns them into ActiveRecord DB > rows. I'm converting images on a filesystem into blobs in a database. > > class ImageFile < ActiveRecord::Base > class << self > def import_from_hash(hash) > %w{medium square thumb lsquare lthumb tiny}.each do |suffix| > filename = "public/item/photos/" + hash[0..2] + "/" + hash + > "_#{suffix}.jpg" > if File.exists?(filename) > File.open(filename, "r") do |file| > image_file = ImageFile.new > eval ("image_file.#{suffix} = file.read") > end > end > end > end > end > end > > As you can see the whole thing depends massively on eval(). Yet I > think it's safe. First, it's only supposed to be run from irb. Second, > the eval's guarded by an array which essentially acts as a filter. It > only ever evals code generated by this code and literals from the > array. (No user input.) > > The suffixes match existing suffixes on the filesystem. They > correspond to different sizes of the same image. I'm essentially > refactoring an architecture here. That's why the redundant data in the > DB. Each image now being represented on the filesystem with > "xyz_square.jpg" will soon become the square attribute of an ImageFile > object. This isn't the cleanest design, but it beats the filesystem > version for my purposes (load-balance-ability and hardware stability). > > Anyway, I think in addition to being safe, this code also shows > something which would end up **significantly** less concise without > eval(). It's kind of deliberately Lispy and functional-programmy. I > would never have written anything like this before reading > "Higher-Order Perl." I think it's a good example of eval() being > useful and safe. But, you know, please knock me down (if you see me > getting high and mighty). > ActiveRecord has the write_attribute and read_attribute methods which is a better choice for what you are doing. You can also use [] and []= as aliases for write_attribute and read_attribute http://ar.rubyonrails.org/classes/ActiveRecord/Base.html Suffixes = %w{medium square thumb lsquare lthumb tiny} class ImageFile < ActiveRecord::Base def ImageFile.import_from_hash(hash) Suffixes.each do |suffix| filename = "public/item/photos/" + hash[0..2] + "/" + hash + "_#{suffix}.jpg" if File.exists?(filename) File.open(filename, "r") do |file| image_file = ImageFile.new self[suffix]=file.read end end end end end -- Brad Phelan http://xtargets.com