【问题标题】:How do you set up MTI in Rails with a polymorphic belongs_to association?如何在 Rails 中使用多态的 belongs_to 关联设置 MTI?
【发布时间】:2021-06-11 23:35:01
【问题描述】:

为了创建Short, Self Contained, Correct (Compilable), Example,假设我想要执行以下操作。

我有一个博客网站。有两种类型的帖子,TextPostLinkPost。还有两种类型的用户,UserGuest。我想用TextPostLinkPost 来实现Multiple Table Inheritance,我的意思是(希望我正确使用了这个词):

  • 在模型级别,我将拥有PostTextPostLinkPostTextPostLinkPost 将继承自 Post
  • 在数据库级别,我将为TextPostLinkPost 的“叶”模型提供表,但不为Post 提供表。

Post 的每种类型都可以属于UserGuest。所以我们有一个多态的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
  has_many :link_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)

【问题讨论】:

    标签: ruby-on-rails inheritance associations polymorphic-associations multi-table-inheritance


    【解决方案1】:
    1. 常量的名称与局部变量的名称相似,只是它们以大写字母开头。

    2. 所有内置类以及您定义的类都有一个对应的全局常量,其名称与名为class name 的类同名。

    因此,在您的情况下,当您定义 User 类时,有一个常量 class nameUser,但没有 user,这就是引发错误 NameError (wrong constant name user) 的原因。

    试试text_post = TextPost.create(title: 'foo', content: 'lorem ipsum', author_id: 1, author_type: 'User')

    【讨论】:

      猜你喜欢
      • 2016-11-14
      • 2011-04-21
      • 2023-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多