【问题标题】:Store child class's name in database column in polymorphic association - rails在多态关联的数据库列中存储子类的名称 - rails
【发布时间】:2017-07-17 09:19:56
【问题描述】:

我有一个类,比如 Car,我从它继承了 Black 和 Red 类,如下所示:

class Car::Black < Car
end

class Car::Red < Car
end

现在,还有另一个类,比如 CarPurchase,它有很多两种类型的汽车。关联如下:

# In Black and Red models:
has_many :car_purchases, as: :purchasable, dependent:destroy

# In CarPurchase model:
belongs_to :purchasable, polymorphic: true

现在我正在尝试像这样保存 CarPurchases:

black_car.car_purchases.new()   # black_car is an object of class Car::Black

我的数据库有一个名为 purchasable_type 的列。问题是记录是用 purchasable_type 'Car' 而不是 'Car::Black' 保存的。在创建记录时,我也尝试显式保存 purchasable_type。没运气。请帮忙。

【问题讨论】:

  • 我认为这是正确的...您正在使用 STI 和多态...在这种情况下应该设置基类类型...查看多态关联部分了解更多详细信息...@ 987654321@
  • 我之前确实看过那个链接。还是谢谢!
  • 检查一下...这可能会有所帮助archonsystems.com/devblog/2011/12/20/…
  • 再次感谢。仍然没有帮助..

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


【解决方案1】:

你可以这样做:

class Car < ActiveRecord::Base
  self.abstract_class = true
  class Black < Car; end
  class Red < Car; end
end

它存储Car 的原因在ActiveRecord::Associations::BelongsToPolymorphicAssociation#replace_keys 中定义 摘录:

def replace_keys(record)
  super
  owner[reflection.foreign_type] = record.class.base_class.name
end

ActiveRecord::Inheritance::ClassMethods::base_class 摘录:

def base_class
  unless self < Base
    raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord"
  end

  if superclass == Base || superclass.abstract_class?
    self
  else
    superclass.base_class
  end
end

所以如果Carabstract_class,那么它将存储Car::Black,否则base_class 将解析为Car。制作Carabstract_class 不会失去大部分魔力,例如Car::Black 仍然知道它是 table_name

警告使用Car 作为abstract_class 意味着它不能被直接实例化。

例如:

class Car < ActiveRecord::Base
  class Black < Car
  end
end 
Car::Black.base_class.name 
#=> Car
Car::Black.table_name
#=> "cars"
Car.new 
#New Car record
class Car < ActiveRecord::Base
  self.abstract_class = true
end
Car::Black.base_class.name 
#=> Car::Black 
Car::Black.table_name
#=> "cars"
Car.new
#=> NotImplementedError: Car is an abstract class and cannot be instantiated.

【讨论】:

  • 我在这里面临的问题不是将记录保存在 Cars 表下,而是保存在 CarPurchases 表下。在汽车表中保存完整的类名。但在 car_purchases 表中,purchasable_type 是 Car 而不是 Car::Black。另外,上面提到的例子不是我想要实现的。这只是为了解释问题。我正在尝试解决类似的问题。
  • @KeerthanaRaghavan 好的,我现在了解情况。请参阅更新了解潜在的解决方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多