为不同类型的“任务”对象创建ActiveRecord关联列表

时间:2013-12-10 15:23:15

标签: ruby-on-rails ruby activerecord ruby-on-rails-4

我目前有一个名为tasks的通用任务表,其中包含任何任务需要的基本要素(公共属性)。

  create_table "tasks", force: true do |t|
    t.integer  "agent_id"
    t.datetime "start"
    t.text     "note"
    t.string   "status"
    t.datetime "create_date"
  end

我还想要与tasks对象相关的多种类型的任务,例如followupreview_sales_office。这两个都包含不同的细节,但它们在技术上都是tasks的类型。

  create_table "followups", force: true do |t|
    t.integer "account_id"
    t.integer "task_id"
    t.integer "account_contact_id"
    t.string  "contact_method"
  end

  create_table "review_sales_offices", force: true do |t|
    t.integer "sales_office_id"
    t.integer "task_id"
    t.integer "sales_office_rep"
  end

如果我只想获取所有后续任务的列表或所有评论销售办公室任务的列表,这些都可以正常工作,但是如何检索按task_datetime排序的所有任务列表,当输出到a时视图可以单击相应类型的任务(任务1和2可能是后续任务,任务3可能是销售办公室审查)。

我可以做一个Task.joins(...)来获取所有任务的集合(我认为这是正确的方法)但是任务本身并不一定知道任务的类型,所以我不确定如何基于任务类型生成适当的链接(理想情况下,链接会像适当的任务类型的编辑页面一样)。

有什么建议吗?

1 个答案:

答案 0 :(得分:2)

当天的话语是:多态关联!

您只需要:

1)将task_details_type:string和task_details_id列添加到任务表中。

2)添加你的任务模型

belongs_to :task_details, polymorphic: true

3)在每个任务类型中添加:

has_one :task, as: task_details

你有一个简单的模型,它会给你正确的task_details而不需要你的类型。另外,你可以使它成为一个包装器:

def method_missing(name, args*, &block)
  return task_details.public_send(name, *args, &block) if task_details && task_details.respond_to? name
  super
end

不幸的是,不可能声明多态的has_one关联,所以我们需要忍受诸如'task belongs_to task_details'之类的无意义 - 生活艰难。