是否可以在子类上获取超类和子类属性?

时间:2021-07-16 10:04:42

标签: ruby-on-rails

假设我有一个继承自 LuxuryAutomobileAutomobile。我想获得像 :num_doors 这样的所有普通属性,但我也想获得像 :num_screens 这样的特殊属性。

create_table :automobiles do |t|
  t.belongs_to :user
  t.integer :num_wheels
  t.integer :num_doors
  t.string :color
end

create_table :luxury_automobiles do |t|
  t.boolean :leather_seats
  t.integer :num_screens
  t.string :custom_monogram
end

所以我继承了汽车的一切:

class LuxuryAutomobile < Automobile


end

我可以获取轮子的数量,但我无法设置或获取屏幕的数量。

porsche = LuxuryAutomobile(num_wheels: 4, user: u)
porsche.num_wheels # => 4
porsche.num_screens #(undefined method `num_screens=' for #<LuxuryAutomobile:0x00007fa1e7cf17b0>)

我基本上想保留子类的功能(它的所有附加属性),但如果某些东西没有实现,它应该从父类中获取。

2 个答案:

答案 0 :(得分:1)

首先,您可以检查 table 指向的数据库 ActiveRecord

class LuxuryAutomobile < Automobile
end
LuxuryAutomobile.table_name # automobiles

所以你必须明确设置数据库表名

class LuxuryAutomobile < Automobile
 self.table_name = "luxury_automobiles"
end
LuxuryAutomobile.table_name # luxury_automobiles

现在类LuxuryAutomobile指向表luxury_automobiles并且还继承了父类logic的{​​{1}}但不是来自表Automobile的数据.

automobiles

因此您必须复制数据表或将 get/set db 属性委托给 class Automobile < ApplicationRecord def decorator "decorator" end end class LuxuryAutomobile < Automobile self.table_name = "luxury_automobiles" end LuxuryAutomobile.first.decorator # "decorator" LuxuryAutomobile.first.num_wheels # nil

Automobile

现在你也可以这样做

# migration
class AddAutomobileRefToLuxuryAutomobiles < ActiveRecord::Migration[6.0]
 def change
   add_reference :luxury_automobiles, :automobile, foreign_key: true
 end
end

class LuxuryAutomobile < Automobile
 self.table_name = "luxury_automobiles"
 belongs_to :automobile
 delegate :num_wheels, to: :automobile
end

LuxuryAutomobile.first.decorator # "decorator"
LuxuryAutomobile.first.num_wheels # 4

答案 1 :(得分:0)

这是可能的,但不是您描述的确切方式。

您需要使用 STI 才能完成此操作。 https://api.rubyonrails.org/classes/ActiveRecord/Inheritance.html


另一个选项是在您的模型中使用 delegate

delegate :user, :num_wheels, :num_doors, :color, to: :parent_car # Replace parent car with whatever the relationship actually is.

但这不允许你这样做:

porsche = LuxuryAutomobile(num_wheels: 4, user: u)

您必须单独创建记录或使用 accepts_nested_attributes

我会使用 STI 来处理您正在做的事情。我不确定基表是否必须是抽象的。这不是我做过的事情。