【问题标题】:rails polymorphic association (legacy database)rails 多态关联(遗留数据库)
【发布时间】:2009-12-30 13:55:56
【问题描述】:

我使用的是旧数据库,因此我无法控制数据模型。他们使用很多多态链接/连接表,像这样

create table person(per_ident, name, ...)

create table person_links(per_ident, obj_name, obj_r_ident)

create table report(rep_ident, name, ...)

其中obj_name 是表名,obj_r_ident 是标识符。 因此,链接报告将按如下方式插入:

insert into person(1, ...)
insert into report(1, ...)
insert into report(2, ...)

insert into person_links(1, 'REPORT', 1)
insert into person_links(1, 'REPORT', 2)

然后人 1 将有 2 个链接的报告,1 和 2。

我可以理解使用这样的数据模型可能带来的好处,但我主要看到一个很大的缺点:使用约束无法确保数据完整性。但是,唉,我不能再改变了。

但是要在 Rails 中使用它,我正在研究多态关联,但没有找到解决这个问题的好方法(因为我无法更改列名,也没有轻易找到解决方法)。

不过,我确实想出了一个解决方案。请提供建议。

class Person < ActiveRecord::Base

  set_primary_key "per_ident"
  set_table_name "person"
  has_and_belongs_to_many :reports,
                         :join_table => "person_links",
                         :foreign_key => "per_ident",
                         :association_foreign_key => "obj_r_ident",
                         :conditions => "OBJ_NAME='REPORT'"
end

class Report < ActiveRecord::Base

  set_primary_key "rep_ident"
  set_table_name "report"
  has_and_belongs_to_many :persons,
                     :join_table => "person_links",
                     :foreign_key => "obj_r_ident",
                     :association_foreign_key => "per_ident",
                     :conditions => "OBJ_NAME='REPORT'"
end

这可行,但我想知道是否会有更好的解决方案,使用多态关联。

【问题讨论】:

    标签: ruby-on-rails ruby polymorphic-associations


    【解决方案1】:

    至少从 Rails 4.2.1 开始,您可以将 foreign_type 传递给 belongs_to 声明,以指定用于多态关联“类型”的列的名称

    http://apidock.com/rails/v4.2.1/ActiveRecord/Associations/ClassMethods/belongs_to

    【讨论】:

      【解决方案2】:

      当然,您可以覆盖列名,但是快速浏览 Rails API 并没有显示任何地方可以覆盖多态“类型”列。因此,您将无法将其设置为 'obj_name'。

      这很难看,但我认为您需要为表中的每种类型的对象提供一个 HABTM。

      您可能能够执行以下操作:

      {:report => 'REPORT'}.each do |sym, text|
        has_and_belongs_to_many sym,
          :join_table => "person_links",
          :foreign_key => "obj_r_ident",
          :association_foreign_key => "per_ident",
          :conditions => "OBJ_NAME='#{text}'"
      end
      

      至少这样所有常见的东西都保持DRY,您可以轻松添加更多关系。

      【讨论】:

      • 确实我也没有找到任何方法来覆盖多态类型列。我希望是我没有找到正确的方向:) 我喜欢你的建议。
      • 你也许可以破解 ActiveRecord 并覆盖该列名,但是...... blech。
      • 您现在可以执行此操作。在此处查看其他答案:stackoverflow.com/a/41179078/26604
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多