如何避免命名空间activerecord模型?

时间:2012-04-23 09:35:51

标签: ruby-on-rails-3 activerecord

我正在使用带有100多个型号的rails 3.2.3。问题是目录app / models太拥挤了。我将目录组织成几个组并添加autoload_paths(用于新的子目录)。我不希望我的模型使用命名空间,因为它最终会变成几个名称空间,这对开发不利。 让我们说:

# app/models/listing.rb
class Listing < ActiveRecord::Base
  has_many :communications
end

# app/models/listing/communication.rb
class Communication < ActiveRecord::Base
end

在我的rails控制台中,除了在activerecord关联中之外,它适用于任何具有绝对引用的模型。我无法调用Listing.first.communications。我看到它正在尝试加载Listing :: Communication,它失败了,因为这个文件的内容是Communication(没有名称空间)。

LoadError: Expected /home/chamnap/my_app/app/models/listing/communication.rb to define Listing::Communication

有没有办法将模型分组到目录中并在没有命名空间的情况下使用它们?或者有没有办法预加载所有模型,以便Rails不会动态加载模型?

2 个答案:

答案 0 :(得分:5)

Rails 3中的子目录和关联中的模型存在问题。我也偶然发现了这一点。

我的解决方案是为每个在子目录中建模的关联指定一个显式的:class_name,比如

class Listing < ActiveRecord::Base
  has_many :communications, :class_name => "::Communication"
end

注意在模型名称之前使用“::” - 它告诉rails,通信模型没有名称空间。

答案 1 :(得分:2)

# e.g. subscription/coupon defines ::Coupon, would would blow up with expected coupon.rb to define Subscription::Coupon
# to remove this:
# a: namespace the models
# b: move them to top-level
# c: add :class_name => "::Coupon" to all places where they are used as associations
ActiveRecord::Reflection::MacroReflection.class_eval do
  def class_name_with_top_level
    "::#{class_name_without_top_level}".sub("::::","::")
  end
  alias_method_chain :class_name, :top_level
end