简体   繁体   English

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

[英]Rails namespace class same as existing active_record model

I'm having a bit trouble with the namespaces in Rails 4. 我在Rails 4中的命名空间有点麻烦。

I have ActiveRecord models Shop , Order , and OrderItem 我有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

I'm replicating the relationship between Order and OrderItem in a namespace like this 我在这样的命名空间中复制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

So my problem is that when I initialize Shop::Order.new , sometimes its order_items is an array of OrderItem s instead of Shop::OrderItem s, and when I test it in the controller, if I type Shop::OrderItem , it will return OrderItem . 所以我的问题是,当我初始化Shop::Order.new ,有时它的order_items是一个OrderItem的数组而不是Shop::OrderItem ,并且当我在控制器中对其进行测试时,如果键入Shop::OrderItem ,它将将返回OrderItem

I'm wondering if Shop::OrderItem wasn't initialized before OrderItem and cause the issue? 我想知道Shop::OrderItem是否在OrderItem之前未初始化并导致问题?

You are running into a namespace collision. 您正在遇到名称空间冲突。 Depending on where the code is executing, Shop could be the ActiveRecord model that you've defined in models/shop.rb , or it could be the module namespace that you've defined under models/shops/*.rb . 根据代码执行的位置, Shop可以是您在models/shop.rb定义的ActiveRecord模型,也可以是您在models/shops/*.rb models/shop.rb下定义的模块名称空间。 Not only will this cause unpredictable execution, it's also confusing to read. 这不仅会导致不可预测的执行,而且还会使阅读变得混乱。

I recommend using a module namespace other than "Shop". 我建议使用“商店”以外的模块名称空间。 Even calling it "MyShop" would be an improvement. 即使称它为“ MyShop”也将有所改进。 However you'll probably still run into naming collisions between Shop and MyShop::Shop . 但是,您可能仍然会在ShopMyShop::Shop之间命名冲突。 You should probably rename the Shop class under the MyShop module to avoid this: 您可能应该在MyShop模块下重命名Shop类以避免这种情况:

For example: 例如:

# model/my_shop/my_order.rb
class MyShop::MyOrder
  # ...
end
# model/my_shop/my_order_item.rb
class MyShop::MyOrderItem
  # ...
end

Having said all that, I feel like you're setting yourself up for a world of hurt. 说了这么多,我觉得您正在为一个受伤的世界做好准备。 This problem might be better solved using service objects. 使用服务对象可以更好地解决此问题。 Google up "Rails Service Objects" for some really good examples. Google提出了“ Rails服务对象”的一些非常好的例子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM