模型可以属于STI子代吗?

时间:2018-10-22 06:36:25

标签: ruby-on-rails associations single-table-inheritance

我有一个基类Place和使用STI约定的多个子类。我有一个单独的模型Post,该模型belongs_toPlace的子类之一:

class Place < ApplicationRecord
end

class SubPlace < Place
  has_many :posts, class_name: "SubPlace", foreign_key: "sub_place_id"
end

class Post < ApplicationRecord
  belongs_to :sub_place, class_name: "SubPlace", foreign_key: "sub_place_id"
end

可以使用Rails控制台保存新的Post记录,但是在尝试为特定Posts查找SubPlace时遇到以下错误:

ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR:  column places.sub_place_id does not exist)

是否可以进行这项工作,或者我的关联必须仅与基类相关?

添加的架构:

create_table "posts", force: :cascade do |t|
    t.string "title"
    t.bigint "sub_place_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["sub_place_id"], name: "index_posts_on_sub_place_id"
end

create_table "places", force: :cascade do |t|
    t.string "name"
    t.string "type"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
end

2 个答案:

答案 0 :(得分:1)

  

ActiveRecord :: StatementInvalid(PG :: UndefinedColumn:ERROR:列   place.sub_place_id不存在)

您在SubPlace中的关联无效。您应该将其重写为

class SubPlace < Place
  has_many :posts
end

答案 1 :(得分:1)

处理关联和STI的更好方法是将关联设置为基类:

class Place < ApplicationRecord
end

class SubPlace < Place
  has_many :posts, foreign_key: 'place_id', inverse_of: 'place'
end

class AnotherKindOfPlace < Place
  has_many :posts, foreign_key: 'place_id', inverse_of: 'place'
end

class Post < ApplicationRecord
  belongs_to :place
end

由于Post不知道或不在乎有不同种类的地方,因此这使事情变得简单明了。当您访问@post.place时,ActiveRecord会读取places.type列,并将实例化正确的子类型。

如果基本Post类也具有关联,则只需将其编写为:

class Place < ApplicationRecord
  has_many :posts, foreign_key: 'place_id', inverse_of: 'place'
end