"Wirtualne" atrybuty

Buduję aplikację, w której user (a nie schemat bazy) określa jakie dane są w rekordach. Dla uproszczenia: dane to tylko stringi.

Np. pod adresem:

/collections/76/items

…może być lista rekordów postaci: [tytuł, wykonawca, rok]

a pod adresem:

/collections/3/items

…może być zupełnie inna kolekcja “Pracownicy” z rekordami postaci: [imię, nazwisko, wiek]

Wymyśliłem sobie schemat z tabelą fields (collection_type_id:integer, name:string, required:boolean, sort_order:integer), a każdy item posiada n * item_field (item_id:integer, field_id:integer, value:string).

No i to generalnie działa, ale muszę się pożegnać z prawie całą magią ActiveRecordu. Tzn takie patenty jak has_many czy sortowanie trzeba robić ręcznie.

I w związku z tym się zastanawiam… czy nie próbuję aby wynaleźć koła? Czy ktoś robił coś takiego? Znacie może jakieś gemy/pluginy z taką funkcjonalnością?
Drugie pytanie: czy to się aby nie kwalifikuje pod CouchDB? Macie doświadczenia z bazą tego typu?

Kwalifikuje się, użyj CouchDB albo Tokyo Tyrant.

Odradzam tworzenie elastycznej struktury jeżeli to tylko możliwe. Robiłem coś takiego kilka razy i potem żałowałem :slight_smile:

Problemy:

  • tracisz wsparcie frameworku, który jest przystosowany do pracy na relacyjnej bazie - to już chyba odczułeś
  • wydajność zapytań wyszukujących po atrybutach (dla małej aplikacji bez znaczenia, dla dużej ogromne)
  • brak standardowego modelu skutecznie utrudnia integrację z innymi systemami, migrację danych do innego systemu
  • niektóre pola które miały być zwykłymi ‘propertisami’ okazują się mieć wpływ na logikę biznesową i żeby je oprogramować musisz robić brzydkie haki w kodzie

Generalnie da się to zrobić, ale korzyści są o wiele mniejsze niż koszty(oczywiście to czasem jest jedyne rozwiązanie). Jeżeli chcesz dodać te pola, żeby umożliwić danemu użytkownikowi ‘customizację’ aplikacji, bo nie jesteś teraz w stanie przewidzieć jakie pola są potrzebne, to zdecydowanie odradzam. W takiej systuacji lepiej zacząć z małą ilością pól i modyfikować model w oparciu o sugestie użytkowników (sprawdzony sposób).

Jeżeli jednak się skusisz to polecam zacząć szukanie od EAV(tak nazywa się to podejście)
http://en.wikipedia.org/wiki/Entity-Attribute-Value_model,
http://stackoverflow.com/search?q=eav
http://inrails.wordpress.com/

To jest tak naprawdę podstawowa funkcja aplikacji (taki free-form CRUD), więc zrezygnować nie mogę :slight_smile:
Dzięki za linki.