【问题标题】:Rails - Adding Custom Fields at runtime in ActiveRecordRails - 在运行时在 ActiveRecord 中添加自定义字段
【发布时间】:2011-01-13 02:54:49
【问题描述】:

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

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

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


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

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

我正在尝试找出在 Rails 中实现这种设计的最佳方法。会有很多模型允许扩展简单属性。

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

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    类似...?

    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
    

    【讨论】:

    • 使用注入可能会更好。像 self.field_values.inject({}) { |memo, fv| memo[fv.field_definition] = fv } 或类似的。
    • 这是我想我会使用的......想知道是否有更“红宝石”的方式来做到这一点......
    • 通常的方法可能根本不使用哈希,而只使用生成的关联方法,但我想你特别想要一个哈希是有原因的......?
    • 我在想 person.meta[:twitter] 或类似的东西。随意教育我一些更清洁的东西:)
    【解决方案2】:

    看看Friendly ORM。它允许您在没有模式的情况下使用 mysql。它的灵感来自blog post,关于 Friendfeed 如何使用 mysql 存储无模式数据。

    Friendly 将取代 ActiveRecord,尽管您可以很容易地在 Friendly 模型旁边使用 ActiveRecord 模型。

    【讨论】:

    • 不完全是我正在寻找的东西,但仍然是一个很酷的发现。 +1
    • 如果您确实考虑无模式数据,您可能希望考虑使用像 CouchDB 或 MongoDB 这样的文档数据库(有关在 Rails 应用程序中使用 MongoDB 和 MongoMapper gem 的网络广播,请参阅 railscasts.com/episodes/194-mongodb-and-mongomapper ; 瑞恩·贝茨 (Ryan Bates) 棒极了)。
    • 是的,我对此很感兴趣。我在 Heroku 上,目前它不适用于 MongoDB。
    【解决方案3】:

    如果您的意图是让您的FieldDefinition 记录属于不同 模型(例如,指向SqueekyToyItemBalloonItem 的列item_id)那么什么你想要的是一个多态关联。

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

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

    【讨论】:

    • 我确实打算在许多模型上使用它们,但它们都将继承自 Item(或者我的基类最终是什么)
    猜你喜欢
    • 2017-08-08
    • 2015-08-29
    • 1970-01-01
    • 2015-05-04
    • 2012-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多