A Story of REST vs WS-*

Elliotte Rusty Harold has an entertaining story of REST and WS-* in the real world. One that involves air-conditioners. It wouldn’t take a genius to see that he’s in favour of RESTful interfaces as opposed to using Web Services. Personally, I haven’t had much experience with the implementation of external services using either, so it was a humorous read at least.

Comments

Oreilly interview with Zed Shaw on Ruby, Mongrel and Rails

Zed Shaw shares his insights and experiences in building Mongrel.

Comments

Automatically creating files for file_column models in Fixtures

I wanted to be able to have my testing regime automatically create files associated with model fixtures defined in the fixture files. Coincidentally, I'm using Sebastien Kanthak's file_column plugin for managing files in models.

After looking at the Fixture class and the FileColumn module, I realised that I needed a way to store the model attribute(s) that were passed in the call to file_column. What FileColumn did was create the methods according to the attribute passed into the method but the attribute itself is not actually stored anywhere.

Time to extend FileColumn:

RUBY:
  1. require File.join(RAILS_ROOT, 'vendor', 'plugins', 'file_column', 'lib', 'file_column')
  2.  
  3. module FileColumn
  4. module ClassMethods
  5. @@file_column_attributes = {}
  6. alias :aliased_file_column :file_column
  7. def file_column(attr, options = {})
  8. aliased_file_column(attr, options)
  9. klass = self.name.constantize
  10. @@file_column_attributes[klass] ||= []
  11. @@file_column_attributes[klass] <<attr
  12. end
  13.  
  14. def file_attributes
  15. @@file_column_attributes[self.name.constantize]
  16. end
  17. end
  18. end

As the name implies, the methods in ClassMethods are class methods on the including class. So in order to store the file_column attributes, we need a class variable, @@file_column_attributes. This variable is a hash with the model class name as the key and an array containing the attributes.I'll also implement a class method so that I'll be able to do Model.file_attributes and know what attributes have been file_columnised.

Next, we'll need to change the way fixtures are populated to the test database. This involves extending the Fixtures class.

We'll do this in test_helper.rb

RUBY:
  1. require 'fileutils'
  2. class Fixtures
  3. SAMPLE_FILE = File.join(Test::Unit::TestCase.fixture_path, 'files', 'sample.pdf')
  4. include FileUtils
  5.  
  6. alias :original_insert_fixtures :insert_fixtures
  7.  
  8. def insert_fixtures
  9. original_insert_fixtures
  10. create_files(@class_name, values) unless @class_name.constantize.file_attributes.nil?
  11. rescue NameError
  12. # workaround for HABTM fixtures
  13. end
  14.  
  15. def create_files(klass, values)
  16. model_dir = File.join(Test::Unit::TestCase.fixture_path, 'media', 'uploads', klass.downcase)
  17. values.each do |fixture|
  18. klass.constantize.file_attributes.each do |attr|
  19. create_file(fixture, attr, model_dir) unless attr.nil?
  20. end
  21. end
  22. def create_file(fixture, attribute, parent_dir)
  23. attribute = attr.to_s
  24. dest_dir = mkpath(File.join(parent_dir, attribute, fixture['id'].to_s))
  25. file_dest = File.join(dest_dir, fixture[attribute])
  26. cp(SAMPLE_FILE, file_dest) unless fixture[attribute].nil? or File.exists?(file_dest)
  27. end
  28. end

The extended insert_fixtures method first invokes original_insert_fixtures, then checks whether the model has any file_column attributes. If it does, the files defined in the fixtures will be created if they don't already exist.

EDIT: Running functional tests with rake test:functionals fails miserably even though running the tests individually is just fine.

2 Comments