Kob*_*ius 4 ruby-on-rails associations single-table-inheritance
我有一个Place使用 STI 约定的基类和多个子类。我有一个单独的模型Post,它belongs_to是以下子类之一Place:
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
Run Code Online (Sandbox Code Playgroud)
可以使用 Rails 控制台保存新记录,但在尝试查找特定记录Post时出现以下错误:PostsSubPlace
ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR: column places.sub_place_id does not exist)
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点,或者我的关联必须仅与基类相关?
添加架构:
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
Run Code Online (Sandbox Code Playgroud)
处理关联和 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
Run Code Online (Sandbox Code Playgroud)
这使事情变得美好和简单,因为Post不知道或关心有不同类型的地方。当您访问@post.placeActiveRecord 时,读取该places.type列并将实例化正确的子类型。
如果 Place 基类也有关联,您只需将其写为:
class Place < ApplicationRecord
has_many :posts, foreign_key: 'place_id', inverse_of: 'place'
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1290 次 |
| 最近记录: |