#ruby-on-rails #ruby
Вопрос:
У меня есть унаследованный код, и я нахожусь в процессе его обновления до Rails 3.1. Я очень близок к завершению, но у меня ошибка.
В консоли Rails я запускаю User.first
и получаю эту ошибку
undefined local variable or method `acts_as_userstamp' for #<Class:0x000000046bef50>
Теперь acts_as_userstamp
это метод, расположенный во второй строке внутри моей пользовательской модели
class User < ActiveRecord::Base
#TODO /lib is not loading??? or is it??? why this method not work in browser?
acts_as_userstamp
И определяется в файле под названием app/lib/model_modifications.rb
.
Теперь я недавно обнаружил, что моя app/lib
папка не загружалась автоматически в мой application.rb
файл, и я думаю, что это исправлено…или это так? Верен ли этот файл? Или нет?
require File.expand_path('../boot', __FILE__)
require 'rails/all'
# evil outdated soap middleware, TODO: kill it with fire
# Does this have to be loaded BEFORE the first line???
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', "vendor", "soap4r"))
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', "vendor", "plugins", "soap4r-middleware", "lib"))
# evil outdated soap middleware, TODO: kill it with fire
require 'soap4r-middleware'
require File.join(File.dirname(__FILE__), '..', 'app', 'lib', 'soap.rb')
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
Bundler.require *Rails.groups(:assets => %w(development test))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
end
module MyappDev
class Application < Rails::Application
# startup the lib directory goodies <-- IS THIS CORRECT???
# config.autoload_paths << "#{Rails.root}/lib"
# config.autoload_paths = %W( lib/ )
config.autoload_paths = %W(#{config.root}/lib)
config.autoload_paths = Dir["#{config.root}/lib/**/"]
# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters = [:password]
config.middleware.use MyAPIMiddleware
end
end
Я пытаюсь отладить этот файл, когда публикую это сейчас. Вот пик его внутренней структуры…(я просто включил общую структуру для краткости)
приложение/библиотека/model_modificatons.rb
class Bignum
...
end
class Fixnum
...
end
class ProcessorDaemon
...
end
module ActiveRecord
module UserMonitor
...
end
module MyLogger
...
end
end
class Object
...
end
class Struct
...
end
class String
...
end
class Fixnum
...
end
class OpenStruct
...
end
class ActiveRecord::Base
def self.visible_columns
...
end
...
def self.acts_as_userstamp
logger.info "HI fonso - acts_as_userstamp is called"
include ActiveRecord::UserMonitor
end
...
protected
def self.range_math(*ranges)
...
end
end
class Array
...
end
class DB
...
end
Если вы можете обнаружить проблему с общей структурой или где-либо еще, пожалуйста, дайте мне знать.
Так почему же этот метод не найден? Я пытаюсь отладить его, когда публикую это, и ничего не получаю.
Я подозреваю, что файл app/lib/model_modifications.rb
не загружается. Что ничего в каталоге /lib не загружается..но как мне это подтвердить?
Спасибо, что дочитали до этого места, надеюсь, я не слишком много наговорил.
Комментарии:
1. Вы всегда можете поместить руководство
require
вapplication.rb
Ответ №1:
autoload_path
конфигурация не загружает все заданные файлы при загрузке, но определяет папки, в которых rails будет искать определенные константы.
Когда ваше приложение загружено, большинство констант в вашем приложении отсутствуют. У Rails есть «умный» способ задержки загрузки файлов с помощью constant_missing
метода в модуле. В принципе, когда Ruby обнаруживает константу в коде и не может ее разрешить, он выполняет указанный метод. Стандартная реализация этого метода заключается в создании UndefinedConstant
исключения, но rails переопределяет его для поиска во всех autoload_paths
файлах файла с именем, соответствующим отсутствующей константе, требует его, а затем снова проверяет, присутствует ли отсутствующая константа.
Итак, в вашем коде все работает так, как ожидалось, и вам нужно загрузить этот файл расширения вручную. Если вы хотите, чтобы какой-то код выполнялся при загрузке приложения, поместите свой файл в config/initializers
папку.
В стороне: Старайтесь избегать исправления обезьян, когда это возможно. Это может показаться умным, но добавление дополнительных методов к уже перенаселенным классам не облегчит их использование.
Комментарии:
1. Это помогло мне преодолеть этот горб. Спасибо! (Я слышу, как вы исправляете обезьяну, к сожалению, это унаследованный код, поэтому мне приходится иметь дело с ногой, прикрепленной к уху. )