Rails - 在ActiveRecord中在运行时添加自定义字段

时间:2010-02-04 14:54:36

标签: ruby-on-rails activerecord

您知道一些错误跟踪器(和其他软件)如何允许您添加自定义字段吗?

通常,这是通过如下所示的数据结构完成的:

  Items
----------
 ID | NAME | ITEM_TYPE_ID


 FieldDefinitions
---------------------------------------
 ID | ITEM_TYPE_ID | FIELD_NAME | FIELD_TYPE

 FieldValues
---------------------------------------
ID | FIELD_ID | ITEM_ID | VALUE

我正试图找出在Rails中实现此设计的最佳方法。我想要允许扩展简单属性的许多模型。

当我检索Item时,我希望它包含已为该模型定义的添加字段值的哈希值。

3 个答案:

答案 0 :(得分:6)

像......一样的东西?

class Item < ActiveRecord::Base
  has_many :field_values
  has_many :field_definitions, :through => :field_values

  def custom_fields_hash
    cfh = {}
    self.field_values.each |fv|
      cfh[fv.field_definition] = fv
    end
    cfh
  end
end

class FieldValue < ActiveRecord::Base
  belongs_to :item
  belongs_to :field_definition
end

class FieldDefinition < ActiveRecord::Base
  has_many :field_values
  has_many :items, :through => field_values
end

或者,你可以改变

cfh[fv.field_definition] = fv

...到...

cfh[fv.field_definition.field_name] = fv.value

答案 1 :(得分:1)

看看Friendly ORM。它允许您在没有架构的情况下使用mysql。它受到blog post的启发,关于Friendfeed如何使用mysql存储无模式数据。

友好会取代ActiveRecord,尽管您可以非常轻松地使用Friendly模型旁边的ActiveRecord模型。

答案 2 :(得分:1)

如果您打算将FieldDefinition条记录归属于不同的模型(例如,列item_id指向SqueekyToyItemBalloonItem)那么你想要的是一个多态关联。

它基本上允许您有一个item_type列(在item_id列旁边),然后指定它指向的实际项目类型。

ActiveRecord::Associations::ClassMethods的文档中有一个标题“多态关联”。