class Product < ActiveRecord::Base
actable as: :as_product
end
class Car < ActiveRecord::Base
acts_as :product, as: :as_product
end
class Truck < ActiveRecord::Base
acts_as :product, as: :as_product
end
#Table definition
Product
t.id
t.as_product_id
t.as_product_type
Car
t.id
t.vin
宝石档案
gem 'active_record-acts_as'
ruby 3.2.2
Rails 6.1.7.10
该项目已经可以与 acts_as_relation 正常工作,但由于 gem 已被弃用,现在使用 active_record-acts_as 来代替
使用这个 gem 删除了汽车和产品类之间自动发生的连接
示例: 通过 acts_as_relation,查询在表中已定义的 as_product_id 和 as_product_type 列的帮助下生成汽车和产品之间的联接
p = Product.last
p.vin #This use to give Vin from Car table
使用 active_record-acts_as 控制台/终端上没有加入查询
p = Product.last
p.vin #Now it throws error saying undefined method `vin' for #<Product>
注意 当使用 acts_as_relation 时,该项目的开始迁移如下
create_table "products", :as_relation_superclass => true do |t|
end
现在使用新的 gem active_record-acts_as 已通过运行以下迁移进行更新
change_table :products, :as_relation_superclass => false do |t|
end
这可以使用
https://github.com/chaadow/active_record-acts_as的
specific
方法获得
products(dev)> p = Product.last
=>
#<Product:0x00007432c503aa18
id: 1,
created_at: "2024-12-20 02:57:13.912331000 +0000",
updated_at: "2024-12-20 02:57:13.912331000 +0000",
as_product_type: "Car",
as_product_id: 1>
products(dev)> p.specific
=> #<Car:0x00007432c5030018 id: 1, created_at: "2024-12-20 02:57:13.910996000 +0000", updated_at: "2024-12-20 02:57:13.910996000 +0000", vin: "Foo">
products(dev)> p.specific.vin
=> "Foo"
如果需要,您可以使用
delegate :vin, to: :specific
或以下 hack 来复制旧 gem 的行为:
def method_missing(meth, *args, &block)
return specific&.send(meth) if specific.respond_to? meth
super
end
products(dev)> Product.last.vin
Product Load (0.1ms) SELECT "products".* FROM "products" ORDER BY "products"."id" DESC LIMIT 1 /*application='Products'*/
Car Load (0.0ms) SELECT "cars".* FROM "cars" WHERE "cars"."id" = 1 LIMIT 1 /*application='Products'*/
=> "Foo"