0

我有一个 Rails 4 应用程序,用户在其中定义例如tools数据库并创建存储品牌、年份等项目的字段。然后根据他们定义的字段在他们面前呈现一个 CRUD 界面。

现在我有一个看起来像这样的数据库模型:

class Database < ActiveRecord::Base

  has_many :fields

和一个看起来像这样的字段模型:

class Field < ActiveRecord::Base
  belongs_to :database

基本上,现在在“添加字段”页面上(在您创建数据库并定义字段之后),我正在创建一个唯一 ID 并将其与该页面上的所有字段一起存储,然后我使用它来分组字段进入“行”(使用 rails groupby 语句)。

我有两个问题:1.实现“数据库”的最有效方式是什么?2. 我不知道如何最好地将创建数据库时定义的字段名称与 CRUD 界面中的字段联系起来。例如,如果我name在最初定义所有字段时创建了一个字段,我如何才能将它与 CRUD 界面中的字段相关联?

感谢大家的帮助!如果我需要进一步澄清,请告诉!

4

4 回答 4

2

我建议使用带有 HStore 扩展的 Postgres,因为 ActiveRecord 4 现在支持 hstore 开箱即用。

使用元数据设计来存储属性值在性能方面并不是很有效,一旦 rails 完成了所有模型验证检查,更新就会有点慢,所以我会避免使用它来存储用户数据。

您仍然需要某种模式表来跟踪他们定义的用户属性/字段,包括他们的类型、显示名称、必需/可选等,以便您的应用程序可以正确验证输入并有足够的信息来构建视图。

但 Postgres hstore 运行良好,旨在处理用户定义的数据。Postgres 也支持对 hstore 列的索引和查询,所以它并不慢。

您的设计将需要一张schemas桌子和一张rows桌子。

schemas表将包含其所属用户的列、字段名称、显示名称、类型、范围等。

rows表将包含其所属用户的列,以及一个 values hstore 列,用于保存用户在其架构中定义的所有值。

有关详细信息和操作方法,有很多简单的指南,只需 google “hstore ActiveRecord 4”,因为官方文档似乎还没有跟上。

于 2013-10-07T15:25:46.303 回答
1

我不知道你的商业模式,但我不知道制作一个全新的数据库是否是你所追求的。这看起来需要一个键/值存储。postgres 有一个 hstore。

我会在您的数据库表上使用 postgres hstore,其中每一行代表一个数据库,并且 hstore 包含代表每个任意字段的键/值列表。

于 2013-09-29T02:04:59.763 回答
1

我不太清楚最终目标是什么,但是您可以让您的 Field 模型具有名称、类型、值和用户,这是与 User 模型的关系。显然,1 个用户有很多字段。

假设用户 Bob 创建了“产品名称”和“产品价格”字段。他的 UI 会有“产品名称”和“产品价格”的文本框。价格框可能有一个下拉菜单,上面写着“小于、大于、等于”,因为您知道类型是数字。因此,您的查询基本上会在伪 SQL 中说“选择用户 Bob 的所有字段,其中名称是“产品名称”,值是(或类似)产品名称文本框中给出的名称,名称是“产品价格”和值是 (<|=|>) 产品价格文本框中给出的值(在解析为数字之后)。

也许。

如果一切都失败了,请考虑按照您希望的方式编写代码。从代码到数据库结构而不是典型的其他方式会非常有帮助。

希望有帮助。

于 2013-10-06T16:30:52.193 回答
0

出于某种原因,我无法附上 DB 对象的类图,但尝试从下面的表结构中获取该 idiea。

从最终用户的角度来看,他/她将查看 UI 上的字段名称列表。然后将它们中的一些拉到 UI 上的某个独特位置以指示它们在一起。这将形成一个新的数据库。我们看待它的另一种方式是,它只不过是桌子。我参与了一个项目,我们试图通过读取表定义来通过 C# 代码动态生成 CRUD。如果您查看下图,这可能会消除一些疑问。基本上我们需要存储一些元数据表,代码可以使用它来构建 CRUD。下面是您可以开始使用的示例数据库对象。根据您想要的复杂程度和复杂程度,您可以为其添加更多功能。

    DECLARE @_DBField TABLE
    (
        ID      INT IDENTITY NOT NULL
        ,NAME   sysname NOT NULL
    )
    DECLARE @_FieldDataTypeID TABLE
    (
        DataTypeID      INT IDENTITY NOT NULL
        ,SqlDataType    sysname NOT NULL
        ,DisplayName    sysname NOT NULL
    )
    DECLARE @_DB TABLE
    (
        ID          INT NOT NULL
        ,DBName     sysname NOT NULL
        ,FieldID    INT NOT NULL
        ,DataTypeID INT NOT NULL
        ,IsPartofPK BIT NOT NULL DEFAULT 0
    )

    INSERT INTO @_DBField( NAME )   
    SELECT 'FName' 
    UNION ALL   SELECT 'LName' 
    UNION ALL   SELECT 'MName'

    INSERT INTO @_FieldDataTypeID( SqlDataType ,DisplayName)
                SELECT 'NVARCHAR(50)'       ,'Short-String; Alphanumeric value'
    UNION ALL   SELECT 'NVARCHAR(200)'      ,'Midium-String; Alphanumeric value'
    UNION ALL   SELECT 'NVARCHAR(500)'      ,'Long-String; Alphanumeric value'
    UNION ALL   SELECT 'NVARCHAR(MAX)'      ,'Max-String; Alphanumeric value'
    UNION ALL   SELECT 'INT'                ,'Small-Integer; Integer Value'
    UNION ALL   SELECT 'BIT'                ,'0 or 1; Boolean Value'


    INSERT INTO @_DB( ID ,DBName ,FieldID ,DataTypeID ,IsPartofPK )
                SELECT 1,'Student_Name',1,1,1
    UNION ALL   SELECT 1,'Student_Name',2,1,1
    UNION ALL   SELECT 1,'Student_Name',3,1,0

    SELECT * FROM @_DB
于 2013-10-02T19:23:32.363 回答