如何在Rails中为具有单表继承的人和公司建模?

时间:2017-08-04 10:41:51

标签: ruby-on-rails activerecord sti

在我的帐单结算应用中var immobles_destacats = ($('#immobles_destacats').length > 0) ? new Vue({ el: '#immobles_destacats', data: { immobles: [] }, methods: { add: function(i) { alert(this.immobles[i].imatges.lenght) alert(this.immobles[i].counter) if (this.immobles[i].imatges.lenght == this.immobles[i].counter) { return this.immobles[i].counter = 0; } return this.immobles[i].counter++; }, substract: function(i) { alert(this.immobles[i].counter) if (this.immobles[i].counter == 0) { return this.immobles[i].counter = this.immobles[i].imatges.lenght; } return this.immobles[i].counter--; } }, mounted: function() { $.post('get_immobles_destacats', function(immobles, textStatus, xhr) { for (var i = 0; i < immobles.length; i++) { immobles[i].counter = 0; immobles_destacats.immobles.push(immobles[i]); } }); } }) : null; 可以发送到invoicescompany。据我了解,这是Rails的一个很好的用例。单表继承(STI)。由于这两种类型共享许多属性和函数,我认为超类person可能是一个很好的方法:

Recipient

我也理解我需要class Recipient < ActiveRecord::Base end class Company < Recipient has_many :people end class Person < Recipient belongs_to :company end 模型中的属性type

唯一困扰我的是Recipient可能(或可能不属于)person。如何在Rails中建模?通常,我只是将另一个数据库字段company添加到company_id表。但是这里只有一个表(people)。那怎么办呢?

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

class Recipient < ActiveRecord::Base 
end

class Company < Recipient
  has_many :people, class_name: "Recipient", foreign_key: 'parent_id' 
end

class Person < Recipient
  belongs_to :company, class_name: "Recipient", foreign_key: 'parent_id'
end

只需将parent_id添加到收件人迁移中即可。 这就简单而快速,您可以在has_manybelongs_to之间得到您想要的一个模型两个STI以及companyperson

答案 1 :(得分:1)

结构可能如下所示:

class Recipient < ActiveRecord::Base 
  has_many :invoices
end

class Company < Recipient
  has_many :people
end

class Person < Recipient
  belongs_to :company
end

class Invoice < ActiveRecord::Base
  belongs_to :recipients
end

# Schema
create_table "invoices", force: :cascade do |t|
  t.integer "recipient_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.index ["recipient_id"], name: "index_invoices_on_recipient_id"
end

create_table "recipients", force: :cascade do |t|
  t.integer "company_id"
  t.string "type"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

我刚刚在控制台中尝试过:

> Recipient.all
 => [#<Company:0x007fd55d797220
  id: 1,
  company_id: nil,
  type: "Company",
  created_at: Fri, 04 Aug 2017 10:57:41 UTC +00:00,
  updated_at: Fri, 04 Aug 2017 10:57:41 UTC +00:00>,
 #<Person:0x007fd55d796730
  id: 2,
  company_id: 1,
  type: "Person",
  created_at: Fri, 04 Aug 2017 10:57:41 UTC +00:00,
  updated_at: Fri, 04 Aug 2017 10:57:41 UTC +00:00>,
 #<Person:0x007fd55d796208
  id: 3,
  company_id: nil,
  type: "Person",
  created_at: Fri, 04 Aug 2017 10:57:41 UTC +00:00,
  updated_at: Fri, 04 Aug 2017 10:57:41 UTC +00:00>]

> Person.last.company
  Person Load (0.2ms)  SELECT  "recipients".* FROM "recipients" WHERE "recipients"."type" IN ('Person') ORDER BY "recipients"."id" DESC LIMIT ?  [["LIMIT", 1]]
 => nil

> Person.first.company
  Person Load (0.2ms)  SELECT  "recipients".* FROM "recipients" WHERE "recipients"."type" IN ('Person') ORDER BY "recipients"."id" ASC LIMIT ?  [["LIMIT", 1]]
  Company Load (0.2ms)  SELECT  "recipients".* FROM "recipients" WHERE "recipients"."type" IN ('Company') AND "recipients"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
 => #<Company id: 1, company_id: nil, type: "Company", created_at: "2017-08-04 10:57:41", updated_at: "2017-08-04 10:57:41">