Rails ActiveRecord_Associations_CollectionProxy 与单表继承

Posted

技术标签:

【中文标题】Rails ActiveRecord_Associations_CollectionProxy 与单表继承【英文标题】:Rails ActiveRecord_Associations_CollectionProxy with Single Table Inheritance 【发布时间】:2017-06-13 20:39:43 【问题描述】:

我使用单表继承来模拟 Stores、Tailors、Orders 和 TailorOrders。订单属于裁缝,但我无法在 rails 控制台中访问裁缝的订单。商店有多种类型,在数据库中订单有requester_idprovider_id。裁缝与订单的关系始终是提供者。继承模型如下:

class Store
end

class Tailor < Store 
  has_many :orders
end

class Order 
  has_many :items
end 

class TailorOrders
   belongs_to :tailor, class_name: "Tailor", foreign_key: "provider_id"
end

class Item 
  belongs_to :order
end

我能够获取属于订单的商品,如下所示:

Order.first.items
#=>  [#<Item:0x007fe9f0cc8f58
  id: 1,
  order_id: 1,
  name: "Grey Pants",
  created_at: Tue, 13 Jun 2017 17:50:57 UTC +00:00,
  updated_at: Tue, 13 Jun 2017 17:50:57 UTC +00:00,
  type_id: 1>]

而且,我可以从订单中得到裁缝:

Order.first.tailor
#=> #<Tailor:0x007fe9f214b8b8
 id: 3,
 company_id: 3,
 primary_contact_id: 3,
 phone: "2121468958",
 street1: "640 Bennie Way",
 street2: "Apt. 533",
 city: "Carliefurt",
 state: "New Mexico",
 zip: "42439-4809",
 country: "Ukraine",
 created_at: Tue, 13 Jun 2017 17:50:56 UTC +00:00,
 updated_at: Tue, 13 Jun 2017 17:50:56 UTC +00:00,
 type: "Tailor",
 name: "Joe's on Main Street">

但是,我不能得到属于裁缝的订单:

Tailor.first.orders 
#=> #<Order::ActiveRecord_Associations_CollectionProxy:0x3ff4f786e9e0>

Tailor.first.orders.first
#=> ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column orders.tailor_id does not exist
LINE 1: SELECT  "orders".* FROM "orders" WHERE "orders"."tailor_id" ...

这个错误似乎与我上面描述的数据库布局有关,其中类 Tailor 在订单的 db 表中始终是 provider

有没有办法通过裁缝(一种商店,也是订单表中的提供者)访问订单?我还想完成类似于Stores.first.orders.first.items 的事情。任何帮助将不胜感激!

【问题讨论】:

Tailor 类中为has_many :orders 关联设置foreign_key 选项。现在它期望外键是orders 表中的tailor_id 列,在您的情况下是不同的。 orders 表中是否有一列指向它所属的Tailor @chumakoff 它有效!完美谢谢 【参考方案1】:

我想我会在这里发布解决方案,以防其他人遇到这个问题。根据@chumakoff 的评论,我只是像这样调整了 Tailor 类:

之前

class Tailor < Store 
  has_many :orders
end

之后

class Tailor < Store
  has_many :orders, foreign_key: "provider_id"
end

【讨论】:

【参考方案2】:

AddTailorToOrders 创建迁移。应该是这样的

rails g migration AddTailorToOrders tailor:references

class AddTailorReferenceToOrders < ActiveRecord::Migration def change add_reference :orders, :tailor, index: true end end

这将在 Order 表中创建一个引用 Tailor 的列 tailor_id

【讨论】:

订单的数据库模式确实有一个 provider_id 列,这在我们的例子中是必要的,因为裁缝不会是唯一满足它的商店

以上是关于Rails ActiveRecord_Associations_CollectionProxy 与单表继承的主要内容,如果未能解决你的问题,请参考以下文章

markdown [rails:devise] Ruby on Rails的身份验证gem。 #ruby #rails

Rails:如何在 Rails 中为 Devise 设置密钥?

从 Rails 2 到 Rails 3 路由

Rails:在 Rails 控制器中捕获所有异常

如何在带有 Rails 4.2 的专用调试端口上使用工头启动 Rails?

Rails 4 的 Rails_admin 批量分配错误