Ruby on rails 表单中的Rails多态关联

Ruby on rails 表单中的Rails多态关联,ruby-on-rails,polymorphism,polymorphic-associations,Ruby On Rails,Polymorphism,Polymorphic Associations,这是多态关联的一个稍微独特的版本。这是一个我一直在努力解决的“现实世界”问题,但没有找到很多好的答案,所以我自己解决了 一个事务记录有许多任务,每个任务都有一个受让人,可以来自多个表 # Models class Transaction < ApplicationRecord has_many :tasks has_many :borrowers has_many :partners # Combine into a single array to display on

这是多态关联的一个稍微独特的版本。这是一个我一直在努力解决的“现实世界”问题,但没有找到很多好的答案,所以我自己解决了

一个
事务
记录有许多
任务
,每个
任务
都有一个
受让人
,可以来自多个表

# Models
class Transaction < ApplicationRecord
  has_many :tasks
  has_many :borrowers
  has_many :partners

  # Combine into a single array to display on the collection_select
  def assignees
    borrowers + partners
  end
end

class Task < ApplicationRecord
  # has attribute :assignee_type_and_id (string)

  belongs_to :transaction

  # Reverse engineer single attribute into type/id parts
  def assignee
    if assignee_type_and_id
      parts = assignee_type_and_id.split(".")
      type = parts.first
      id = parts.last

      if type.to_s.downcase == "borrower"
        Borrower.find(id)
      elsif type.to_s.downcase == "partner"
        Partner.find(id)
      end
    end
  end
end

class Borrower < ApplicationRecord
  # has attribute :name
  belongs_to :transaction

  def type_and_id
    "borrower.#{id}"
  end
end

class Partner < ApplicationRecord
  # has attribute :name
  belongs_to :transaction

  def type_and_id
    "partner.#{id}"
  end
end
提交表单时,它以
forror.123
partner.57
等格式发布值,该值存储在DB列中

当我想要检索实际任务的
受让人
时,我必须做一点逆向工程,如上文在
任务#受让人
方法中所述

问题

有没有更合适的方法?我自己想到的,这让我很害怕,因为我知道像这样的问题一定是由比我聪明得多的人解决的

有没有一种方法可以通过“正常”多态性而不是强制使用我自己的混合版本

更新


我偶然发现了Rails4.2+GlobalID,它似乎正是这样做的。除非有理由不使用它,否则我可能使用该实现,而不是我自己的“混蛋”版本。对于这种情况,有没有更好的解决方案?

对于表单跨越多个模型/复杂关联的此类问题,我使用表单支持对象。它保持一切清洁和模块化。这里有一个很好的总结:

对于表单跨越多个模型/复杂关联的此类问题,我使用表单备份对象。它保持一切清洁和模块化。下面是一篇很好的评论:

# form.html.erb
<%= form_for @task do |f| %>
  <%= f.label :assignee_type_and_id, "Assignee" %>

  <%= f.collection_select :assignee_type_and_id, @transaction.assignees, :name, :type_and_id %>
<% end %>