Rails命名空间类与现有的active_record模型相同

时间:2016-05-18 14:06:19

标签: ruby-on-rails ruby-on-rails-4 namespaces

我在Rails 4中的命名空间有点麻烦。

我有ActiveRecord模型ShopOrderOrderItem

# model/shop.rb
class Shop < ActiveRecord::Base

# model/order.rb
class Order < ActiveRecord::Base
  has_many :order_items

# model/order_item.rb
class OrderItem < ActiveRecord::Base
  belongs_to :orderable, polymorphic: true
  belongs_to :order

我在这样的命名空间中复制OrderOrderItem之间的关系

# model/shop/order.rb
class Shop::Order
  attr_accessor :order_items
  def initialize
    self.order_items = []
    self.order_items << Shop::OrderItem.new
  end

# model/shop/order_item.rb
class Shop::OrderItem
  attr_accessor :orderable_type, :orderable_id

  def initialize(params = {})
    if params
      self.orderable_type = params['orderable_type'] if params['orderable_type']
      self.orderable_id = params['orderable_id'] if params['orderable_id']
    end
  end

  def price
    orderable.price
  end

  def orderable
    orderable_type.constantize.find_by(id: orderable_id)
  end

  def to_h
    Hash[
      orderable_type: self.orderable_type,
      orderable_id: self.orderable_id,
      price: self.price
    ]
  end

end

所以我的问题是,当我初始化Shop::Order.new时,有时它的order_items是一个OrderItem而不是Shop::OrderItem的数组,当我在其中测试它时控制器,如果我输入Shop::OrderItem,它将返回OrderItem

我想知道Shop::OrderItem之前OrderItem是否未初始化并导致问题?

1 个答案:

答案 0 :(得分:1)

您正在遇到名称空间冲突。根据代码的执行位置,Shop可能是您在models/shop.rb中定义的ActiveRecord模型,也可能是您在{{1}下定义的模块命名空间}}。这不仅会导致不可预测的执行,而且还会让人感到困惑。

我建议使用&#34; Shop&#34;以外的模块命名空间。甚至称之为&#34; MyShop&#34;会有所改善。但是,您可能仍会遇到models/shops/*.rbShop之间的命名冲突。您应该重命名MyShop模块下的Shop类以避免这种情况:

例如:

MyShop::Shop

说了这么多,我觉得你正在为自己创造一个受伤的世界。使用服务对象可能更好地解决此问题。 Google up&#34; Rails服务对象&#34;一些非常好的例子。