在rails中创建“数据库”

时间:2013-09-29 02:00:38

标签: mysql ruby-on-rails ruby database

我有一个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 个答案:

答案 0 :(得分:2)

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

使用元数据设计存储属性值并不是非常有效的性能,并且一旦rails完成所有模型验证检查,更新就会变慢,所以我会避免它存储用户数据。

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

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

您的设计需要schemas表和rows表。

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

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

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

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

因此,假设用户Bob创建了“产品名称”和“产品价格”字段。他的用户界面会有“产品名称”和“产品价格”的文本框。价格框可能有一个下拉列表,表示“更少,更大,相等”,因为您知道类型是数字。因此,您的查询基本上会在伪SQL中选择“为用户Bob选择所有字段,其名称为”产品名称“,值为(或类似)产品名称文本框中给出的名称,名称为”产品价格“和值是(&lt; | = |&gt;)产品价格文本框中给出的值(解析为数字后)。

可能。

如果所有其他方法都失败了,请考虑编写您想要的代码。从代码到数据库结构而不是典型的其他方式非常有用。

希望有所帮助。

答案 3 :(得分:0)

由于某种原因,我无法附加数据库对象的类图,但试图从下面的表结构中获取它自己。

从最终用户的角度来看,他/她将在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