@@ -10,6 +10,7 @@ module AnnotateModels
1010 # File.join for windows reverse bar compat?
1111 # I dont use windows, can`t test
1212 UNIT_TEST_DIR = File . join ( "test" , "unit" )
13+ MODEL_TEST_DIR = File . join ( "test" , "models" ) # since rails 4.0
1314 SPEC_MODEL_DIR = File . join ( "spec" , "models" )
1415 FIXTURE_TEST_DIR = File . join ( "test" , "fixtures" )
1516 FIXTURE_SPEC_DIR = File . join ( "spec" , "fixtures" )
@@ -32,6 +33,7 @@ module AnnotateModels
3233
3334 TEST_PATTERNS = [
3435 File . join ( UNIT_TEST_DIR , "%MODEL_NAME%_test.rb" ) ,
36+ File . join ( MODEL_TEST_DIR , "%MODEL_NAME%_test.rb" ) ,
3537 File . join ( SPEC_MODEL_DIR , "%MODEL_NAME%_spec.rb" ) ,
3638 ]
3739
@@ -121,7 +123,7 @@ def get_schema_info(klass, header, options = {})
121123 col_type = ( col . type || col . sql_type ) . to_s
122124 if col_type == "decimal"
123125 col_type << "(#{ col . precision } , #{ col . scale } )"
124- elsif col_type != "spatial"
126+ elsif col_type != "spatial"
125127 if ( col . limit )
126128 if col . limit . is_a? Array
127129 attrs << "(#{ col . limit . join ( ', ' ) } )"
@@ -140,7 +142,7 @@ def get_schema_info(klass, header, options = {})
140142 # and print the type and SRID
141143 if col . respond_to? ( :geometry_type )
142144 attrs << "#{ col . geometry_type } , #{ col . srid } "
143- elsif col . respond_to? ( :geometric_type ) and col . geometric_type . present?
145+ elsif col . respond_to? ( :geometric_type ) and col . geometric_type . present?
144146 attrs << "#{ col . geometric_type . to_s . downcase } , #{ col . srid } "
145147 end
146148
@@ -222,7 +224,7 @@ def annotate_one_file(file_name, info_block, position, options={})
222224 old_header = old_content . match ( header_pattern ) . to_s
223225 new_header = info_block . match ( header_pattern ) . to_s
224226
225- column_pattern = /^#[\t ]+\w +[\t ]+.+$/
227+ column_pattern = /^#[\t ]+[ \w \* `] +[\t ]+.+$/
226228 old_columns = old_header && old_header . scan ( column_pattern ) . sort
227229 new_columns = new_header && new_header . scan ( column_pattern ) . sort
228230
@@ -235,10 +237,10 @@ def annotate_one_file(file_name, info_block, position, options={})
235237 # Replace inline the old schema info with the new schema info
236238 new_content = old_content . sub ( PATTERN , info_block + "\n " )
237239
238- if new_content . end_with? ( info_block + "\n " )
240+ if new_content . end_with? ( info_block + "\n " )
239241 new_content = old_content . sub ( PATTERN , "\n " + info_block )
240242 end
241-
243+
242244 # if there *was* no old schema info (no substitution happened) or :force was passed,
243245 # we simply need to insert it in correct position
244246 if new_content == old_content || options [ :force ]
@@ -352,7 +354,7 @@ def get_model_files(options)
352354 models = if options [ :ignore_model_sub_dir ]
353355 Dir [ "*.rb" ]
354356 else
355- Dir [ "**/*.rb" ]
357+ Dir [ "**/*.rb" ] . reject { | f | f [ "concerns/" ] }
356358 end
357359 end
358360 rescue SystemCallError
@@ -369,21 +371,36 @@ def get_model_files(options)
369371 # Check for namespaced models in subdirectories as well as models
370372 # in subdirectories without namespacing.
371373 def get_model_class ( file )
372- # this is for non-rails projects, which don't get Rails auto-require magic
373- require File . expand_path ( "#{ model_dir } /#{ file } " )
374374 model_path = file . gsub ( /\. rb$/ , '' )
375- get_loaded_model ( model_path ) || get_loaded_model ( model_path . split ( '/' ) . last )
375+ begin
376+ get_loaded_model ( model_path ) or raise LoadError . new ( "cannot load a model from #{ file } " )
377+ rescue LoadError
378+ # this is for non-rails projects, which don't get Rails auto-require magic
379+ if Kernel . require ( File . expand_path ( "#{ model_dir } /#{ model_path } " ) )
380+ retry
381+ elsif model_path . match ( /\/ / )
382+ model_path = model_path . split ( '/' ) [ 1 ..-1 ] . join ( '/' ) . to_s
383+ retry
384+ else
385+ raise
386+ end
387+ end
376388 end
377389
378390 # Retrieve loaded model class by path to the file where it's supposed to be defined.
379391 def get_loaded_model ( model_path )
380- ObjectSpace . each_object ( ::Class ) .
381- select do |c |
382- Class === c and # note: we use === to avoid a bug in activesupport 2.3.14 OptionMerger vs. is_a?
383- c . ancestors . respond_to? ( :include? ) and # to fix FactoryGirl bug, see https://github.com/ctran/annotate_models/pull/82
384- c . ancestors . include? ( ActiveRecord ::Base )
385- end .
386- detect { |c | ActiveSupport ::Inflector . underscore ( c ) == model_path }
392+ begin
393+ ActiveSupport ::Inflector . constantize ( ActiveSupport ::Inflector . camelize ( model_path ) )
394+ rescue
395+ # Revert to the old way but it is not really robust
396+ ObjectSpace . each_object ( ::Class ) .
397+ select do |c |
398+ Class === c and # note: we use === to avoid a bug in activesupport 2.3.14 OptionMerger vs. is_a?
399+ c . ancestors . respond_to? ( :include? ) and # to fix FactoryGirl bug, see https://github.com/ctran/annotate_models/pull/82
400+ c . ancestors . include? ( ActiveRecord ::Base )
401+ end .
402+ detect { |c | ActiveSupport ::Inflector . underscore ( c . to_s ) == model_path }
403+ end
387404 end
388405
389406 # We're passed a name of things that might be
@@ -428,7 +445,6 @@ def annotate_model_file(annotated, file, header, options)
428445 end
429446
430447 def remove_annotations ( options = { } )
431-
432448 self . model_dir = options [ :model_dir ] if options [ :model_dir ]
433449 deannotated = [ ]
434450 deannotated_klass = false
0 commit comments