Permalink
Browse files

Find and load our models

Using the Caller class we can track down our models, require the files,
and figure out the class names based on the file names.
  • Loading branch information...
1 parent a6ae0ba commit 9b2ba6d6cc12fb61b4516e459e18d513db6820a4 @vanstee committed Jul 1, 2012
Showing with 64 additions and 0 deletions.
  1. +41 −0 lib/hovercraft/loader.rb
  2. +23 −0 spec/hovercraft/loader_spec.rb
View
@@ -0,0 +1,41 @@
+require 'hovercraft/caller'
+require 'active_support/inflector'
+require 'pry'
@aubreyrhodes

aubreyrhodes Jul 10, 2012

Did you mean to commit this?

@vanstee

vanstee Jul 10, 2012

Owner

Oh no! Thanks man. I need that git commit hook that tells me if I've committed anything matching /pry/

@aubreyrhodes

aubreyrhodes via email Jul 10, 2012

+
+module Hovercraft
+ class Loader
+ def initialize
+ @caller = Caller.new
+ end
+
+ def with_each_model
+ models.each do |model_class|
+ model_name = model_class.name.underscore
+ plural_model_name = model_name.pluralize
+ yield(model_class, model_name, plural_model_name)
+ end
+ end
+
+ def models
+ @models ||= require_models
+ end
+
+ private
+
+ def require_models
+ Dir.glob(File.join(models_directory, '**/*.rb')).map do |file|
+ require file
+ class_from(file)
+ end
+ end
+
+ def models_directory
+ File.join(@caller.directory, 'models')
+ end
+
+ def class_from(file)
+ file.gsub!(/#{models_directory}|.rb/, '')
+ file.classify.safe_constantize
+ end
+ end
+end
@@ -0,0 +1,23 @@
+require 'hovercraft/loader'
+
+describe Hovercraft::Loader do
+ let(:model) { stub(name: 'Robot') }
+ let(:models) { Array.new(3) { model } }
+ let(:params) { models.map { |m| [m, 'robot', 'robots'] } }
+
+ describe '#with_each_model' do
+ before { subject.stub(models: models) }
+
+ it 'yields the class, name, and plural name of each model' do
+ expect { |b| subject.with_each_model(&b) }.to yield_successive_args(*params)
+ end
+ end
+
+ describe '#models' do
+ it 'is memoized' do
+ subject.should_receive(:require_models).once.and_return([])
+
+ 2.times { subject.models }
@aubreyrhodes

aubreyrhodes Jul 10, 2012

It seems like this spec is coupled to the implementation of the class. Why is this tested?

@vanstee

vanstee Jul 10, 2012

Owner

Don't have a good answer for you here so I should probably remove it. Good question.

+ end
+ end
+end

0 comments on commit 9b2ba6d

Please sign in to comment.