2010-02-04 3 views
7

Вы знаете, как некоторые трекеры ошибок (и другое программное обеспечение) позволяют добавлять пользовательские поля?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, я бы хотел, чтобы он включал хэш значений поля добавления, которые были определены для этой модели.

ответ

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

Использование инъекции, вероятно, было бы лучшей формой. Как self.field_values.inject ({}) {| memo, fv | memo [fv.field_definition] = fv} или аналогичный. –

+0

Это то, о чем я думал, что буду использовать ... было интересно, был ли более «рубиновый» способ сделать это ... –

+0

Обычный способ, вероятно, вообще не использовать хеш и просто использовать сгенерированную ассоциацию методы, но я думаю, есть причина, почему вы особенно хотели хэш ...? –

1

Посмотрите на Friendly ORM. Это позволяет работать с mysql без схемы. Это было вдохновлено этим blog post о том, как Friendfeed использует mysql для хранения данных без схем.

Friendly заменит ActiveRecord, хотя вы можете легко использовать модели ActiveRecord рядом с дружественными моделями.

+0

Не совсем то, что я ищу, но прохладная находка, тем не менее. +1 –

+0

Если вы рассматриваете данные без схемы, вам может потребоваться использовать базу данных документов, такую ​​как CouchDB или MongoDB (см. Http://railscasts.com/episodes/194-mongodb-and-mongomapper для веб-трансляции об использовании MongoDB и драгоценный камень MongoMapper в приложении для рельсов, Райан Бэйтс - потрясающий битва). –

+0

Да, я определенно заинтересован в этом. Я нахожусь на Heroku, который в настоящее время не будет работать с MongoDB. –

1

Если вы задумали, чтобы ваши FieldDefinition записи, принадлежащие различных моделей (например, столбец item_id что указует либо SqueekyToyItem или BalloonItem), то, что вы хотите полиморфные ассоциации.

В основном это позволяет вам иметь столбец item_type (рядом с вашим столбцом item_id), который затем указывает фактический тип элемента, на который он указывает.

В документации для ActiveRecord::Associations::ClassMethods имеется заголовок «Полиморфные ассоциации».

+0

Я намереваюсь иметь их на многих моделях, но они все наследуют от Item (или что-то, что заканчивается моим базовым классом) –

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