【问题标题】:How to prevent ActiveRecord to put the namespace of a model in the colum 'type' with Polymorphism如何防止 ActiveRecord 将模型的命名空间放在具有多态性的“类型”列中
【发布时间】:2011-10-25 09:59:25
【问题描述】:

我有一个使用 ActiveRecord 的 ruby​​ 应用程序。我有以下型号

module ExchangeManager
  module Resources
    class Composition < ActiveRecord::Base
      belongs_to :chain
      belongs_to :link, :polymorphic => true, :primary_key => :id
    end

    class Chain < ActiveRecord::Base
      has_many :compositions
    end
  end
end

使用以下迁移

create_table :compositions do |t|
  t.references :link, :polymorphic => true
end

create_table :chains do |t|
  t.string :name, :null => false
end

当我创建一个具有 2 个关联组合的新链时,SQL 表“组合”包含:

标识 |链接ID |链接类型

1 | 1 | ExchangeManager::Resources::Chain

2 | 1 | ExchangeManager::Resources::Chain

我希望 ActiveRecord 只保存短类名,即“Chain”而不是“ExchangeManager::Resources::Chain”,而不是在 link_type 列中包含完整的命名空间。

为什么?因为我在另一个 Rails 应用程序中使用相同的数据库,并且我希望能够在没有命名空间的情况下操作该项目中的相同模型。

【问题讨论】:

  • 如果你只把“Chain”放在数据库中,Rails 将如何在实例化时找到类?
  • Rails 应用程序中的模型不使用命名空间。只有 ruby​​ 应用程序。

标签: ruby activerecord


【解决方案1】:

我想这需要对多态加载机制进行一些修补。我建议不要这样做。

更好的解决方案是使用 您自己的 列来存储没有命名空间的类型。

class FirstModel
  before_save :store_link_type
  def store_link_type
    self.link_short_type = self.link && self.link.class.name.split(':').last # or whatever
    return true
  end
end

class SecondModel
  belongs_to :link, :polymorphic => true, :foreign_type => 'link_short_type'
end

如果您也想从第二个应用更新链接,您还必须执行相反的操作,即预先添加命名空间。

【讨论】:

  • 我明白了,谢谢。确实不是很实用。在 rails 应用程序中使用命名空间会更容易吗?我尝试将它们添加到 rails 模型并更改我的控制器,但出现了错误。
  • @Aymeric,众所周知,ActiveRecord 对命名空间不友好。但是在您的情况下,如果 Rails 应用程序是更大系统的某个前端,我会在应用程序中使用相同的命名空间。看到这篇文章,还是相关的strictlyuntyped.com/2008/08/…
猜你喜欢
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-16
  • 1970-01-01
  • 2015-11-13
  • 2017-06-29
相关资源
最近更新 更多