假设我有一个继承自 LuxuryAutomobile
的 Automobile
。我想获得像 :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>)
我基本上想保留子类的功能(它的所有附加属性),但如果某些东西没有实现,它应该从父类中获取。
答案 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 来处理您正在做的事情。我不确定基表是否必须是抽象的。这不是我做过的事情。