问题描述
为了创建一个 Short,Self Contained,Correct (Compilable),Example,假设我想要执行以下操作。
我有一个博客网站。有两种类型的帖子,TextPost
和 LinkPost
。还有两种类型的用户,User
和 Guest
。我想用 TextPost
和 LinkPost
实现 @L_404_1@,我的意思是(希望我正确使用该术语):
- 在模型级别,我将拥有
Post
、TextPost
和LinkPost
。TextPost
和LinkPost
将从Post
继承。 - 在数据库级别,我将拥有
TextPost
和LinkPost
的“叶”模型表,但没有Post
的表。
每种类型的 Post
都可以属于 User
或 Guest
。所以我们有一个多态的 belongs_to
情况。
我的问题是如何实现这些目标。
我 tried 以下,但它不起作用。
class Post < ApplicationRecord
self.abstract_class = true
belongs_to :author,polymorphic: true # user or guest
validates :title,:author_id,:author_type,presence: true
end
class TextPost < Post
validates :content,presence: :true
end
class LinkPost < Post
validates :url,presence: :true
end
class User < ApplicationRecord
has_many :text_posts,as: :author
has_many :link_posts,as: :author
validates :name,presence: true
end
class Guest < ApplicationRecord
has_many :text_posts,as: :author
end
class CreateTextPosts < ActiveRecord::Migration[6.1]
def change
create_table :text_posts do |t|
t.string :title
t.string :content
t.references :author,polymorphic: true
t.timestamps
end
end
end
class CreateLinkPosts < ActiveRecord::Migration[6.1]
def change
create_table :link_posts do |t|
t.string :title
t.string :url
t.references :author,polymorphic: true
t.timestamps
end
end
end
class createusers < ActiveRecord::Migration[6.1]
def change
create_table :users do |t|
t.string :name
t.timestamps
end
end
end
class CreateGuests < ActiveRecord::Migration[6.1]
def change
create_table :guests do |t|
t.timestamps
end
end
end
控制台输出:
:001 > user = User.create(name: 'alice')
(1.6ms) SELECT sqlite_version(*)
TRANSACTION (0.1ms) begin transaction
TRANSACTION (0.1ms) SAVEPOINT active_record_1
User Create (1.2ms) INSERT INTO "users" ("name","created_at","updated_at") VALUES (?,?,?) [["name","alice"],["created_at","2021-06-11 23:33:38.445387"],["updated_at","2021-06-11 23:33:38.445387"]]
TRANSACTION (0.2ms) RELEASE SAVEPOINT active_record_1
:002'> text_post = TextPost.create(title: 'foo',content: 'lorem ipsum',author_id: 1,author_type:
'user')
Traceback (most recent call last):
1: from (irb):2:in `<main>'
NameError (wrong constant name user)
解决方法
-
常量的名字看起来像局部变量的名字,只是它们以大写字母开头。
-
所有内置类,以及您定义的类,都有一个对应的全局常量,其名称与名为
class name
的类相同。
所以在你的情况下,当你定义 User
类时,有一个常量 class name
: User
,但不是 user
,这就是为什么错误 NameError (wrong constant name user)
被提出。
试试text_post = TextPost.create(title: 'foo',content: 'lorem ipsum',author_id: 1,author_type: 'User')