如何要求具有循环依赖的类?

时间:2013-04-01 00:25:01

标签: ruby ruby-on-rails-3

我被Rail的自动加载丢失的常数所破坏。在Ruby中,如果我有两个类,一个嵌套在另一个中但在不同的文件中,我如何需要它们,因为它们彼此依赖(循环依赖)。

# user.rb
class User < ActiveRecord::Base
   serialize :preferences, User::Preferences
end

# user/preferences.rb
class User::Preferences
end

# user_spec.rb    
require 'user'
require 'user/preferences'

注意:我需要Rails环境。

如果我尝试先加载User,则代码会失败,因为它还不知道User::Preferences。如果我首先加载“user / preferences”,它在加载User时会失败,因为现有的User类不是ActiveRecord的子类。

我怀疑我需要删除循环依赖项,或者如果可能的话,通过传递一个字符串serialize来使'User::Preferences'延迟加载该类,该字符串在需要时被转换为常量。

2 个答案:

答案 0 :(得分:2)

我有一个hack是在user / preferences.rb中创建一个从ActiveRecord :: Base继承的空User类:

class User < ActiveRecord::Base; end

class User::Preferences
end

答案 1 :(得分:0)

不是将User的实现知识汇总到User::Preferences,而是可以将存根声明放在一个公共基础中,如下所示:

# user_base.rb
class User < ActiveRecord::Base; end

# user.rb
require 'user_base'
require 'user/preferences'

class User
   serialize :preferences, User::Preferences
   ...
end

# user/preferences.rb
require 'user_base'

class User::Preferences
end

或者,您可以将User::Preferences移动到独立的模块名称空间,例如ModelHelper::User::Preferences。我想我更喜欢这个解决方案。你有一个循环依赖的事实是代码气味,唯一导致它的是User类作为User::Preferences的命名空间容器的重用。