2013-09-29 6 views
0

У меня есть приложение rails 4, где пользователи определяют, например, базу данных tools, и создают поля, которые хранят такие элементы, как марка, год и т. Д. Затем перед ними предстает интерфейс CRUD на основе полей они определили.Создание «базы данных» в рельсах

Прямо сейчас у меня есть модель базы данных, которая выглядит следующим образом:

class Database < ActiveRecord::Base 

    has_many :fields 

и поля Модель, которая выглядит следующим образом:

class Field < ActiveRecord::Base 
    belongs_to :database 

В принципе, прямо сейчас на странице Добавить Поля (которые после создания базы данных и определения полей), я создаю уникальный идентификатор и сохраняю его со всеми полями на этой странице, которые затем я использую для группировки полей в «строку» (с использованием оператора rails groupby).

У меня есть два вопроса: 1. Самый эффективный способ реализации «базы данных»? 2. Я не могу понять, как наилучшим образом связывать имена полей, которые вы определяете при создании базы данных с полями интерфейса CRUD. Например, если я создаю поле name, когда я изначально определяю все поля, как я могу связать его с полями в интерфейсе CRUD?

Спасибо за помощь! Если мне нужно уточнить больше, скажите!

+1

в базе данных: 'accept_nested_attributes_for: fields' и использовать' fields_for: field' в форме базы данных для создания поля, связанного с вашим объектом базы данных. – MrYoshiji

ответ

2

Я бы рекомендовал использовать Postgres с расширением HStore, поскольку ActiveRecord 4 теперь поддерживает hstore из коробки.

Использование метаданных для хранения значений атрибутов не очень эффективно, а обновления являются медленными, когда рельсы выполняют все проверки своей модели, поэтому я бы избегал его для хранения пользовательских данных.

Вам по-прежнему потребуется какая-либо таблица схем для отслеживания атрибутов/полей пользователей, которые они определяют, включая их тип, отображаемое имя, обязательное/необязательное и т. Д., Чтобы ваше приложение могло правильно проверить ввод и иметь достаточную информацию для сборки вид.

Но Postgres hstore отлично работает и предназначен для работы с определенными пользователем данными. Postgres также поддерживает индексирование и запрос на столбцах hstore, поэтому он не замедляется.

Вашему дизайну понадобится стол schemas и стол rows.

В таблице schemas будут иметь столбцы для пользователя он принадлежит, имя поля, отображаемое название, тип, диапазон и т.д.

В таблице rows будут иметь столбцы для пользователя он принадлежит, и через значения hstore для хранения всех значений, определенных пользователем в их схеме.

Для получения дополнительной информации и практических рекомендаций есть несколько простых руководств только для Google «hstore ActiveRecord 4», поскольку официальная документация, похоже, пока не догнала.

1

Я не знаю вашу бизнес-модель, но я не знаю, является ли создание нового db тем, что вы после. Это похоже на необходимость хранить ключ/значение. postgres имеет hstore.

Я бы использовал postgres hstore в вашей таблице базы данных, где каждая строка представляет базу данных, а hstore содержит списки ключей/значений, представляющие каждое произвольное поле.

+0

Спасибо за ответ. Я не имею в виду создание реальной базы данных, я имею в виду создание приложения, которое действует как «база данных» для пользователя, в котором пользователь может вводить имена и типы полей, а затем представлен интерфейс CRUD для вставки/обновления/удаления основанный на тех месторождениях, которые он/она определил первоначально. Извините за неясность! –

+0

В этом случае вы в основном создаете ключ/значение для каждой «базы данных», –

0

по какой-то причине я не могу прикрепить диаграмму классов объектов БД, но попытаюсь получить эту идентификацию из-под структуры таблицы.

С точки зрения конечного пользователя, он/она будет искать список имени поля в пользовательском интерфейсе. И затем вытащите некоторые из них в уникальное место в пользовательском интерфейсе, чтобы указать, что они вместе. Это создаст новую БД. Мы по-другому смотрим, что это ничего, кроме стола. Я работал над проектом, где мы пытались добиться динамического генерации CRUD через код C#, прочитав определение таблицы. Если вы посмотрите на приведенную ниже диаграмму, это может устранить некоторые сомнения. В основном нам нужно хранить некоторую таблицу метаданных, и код может использовать эту сборку CRUD. Ниже приведены примеры объектов DB, ​​с которых вы можете начать. в зависимости от того, насколько сложный и сложный дизайн вы хотите, вы можете добавить к нему больше функций.

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 
1

Я не совсем ясно, что конечная цель, но вы могли бы иметь модель поля с именем, тип, значение, и пользователь, который является отношение к модели пользователя. Очевидно, что у 1 пользователя есть много полей.

Итак, скажем, пользователь Bob создал поля «Название продукта» и «Цена продукта». Его пользовательский интерфейс будет иметь текстовые поля для «Название продукта» и «Цена продукта». В поле цены может быть выпадающее слово «меньше, больше, равно», связанное с ним, потому что вы знаете, что тип является числовым. Таким образом, ваш запрос будет в основном говорить в pseudoSQL «Выберите все поля для пользователя Bob, где имя« Имя продукта », и это значение (или подобное) - это имя, указанное в текстовом поле Product Name, и имя« Цена продукта »и значение (< | = |>) значение, указанное в текстовом поле «Цена товара» (после разбора числа).

Возможно.

Если все остальное не удается, подумайте о том, как писать код, как вы хотите, чтобы он выглядел. Может быть очень полезно перейти от кода к структуре базы данных, а не к обычным другим способом.

Надеюсь, что это поможет.

Смежные вопросы