Интересни идеи, особено със динамичното създаване на таблици :).
Мисля, че не бих изригнал чак така. Решението ми е нещо като тоя анти-
паттерн, ама с по-нормализирана база данни. Проблема, който трябваше
да спомена е, че вероятно ще дойдат още езици, и тия ми ти опции ще
трябва да се превеждат...
Ето как го направих:
таблици:
users
features
feature_options
feature_options_users
След това идва следната черна магия:
module Features
def self.included(base)
base.class_eval do
has_and_belongs_to_many :features, :class_name =>
'FeatureOption'
end
Feature.find(:all).each do |char|
method = char.name.gsub(' ', '_').underscore
id =
char.id
base.class_eval <<METHODS
def #{method}()
@#{method} ||= features.to_a.find {|feature|
feature.feature_id == #{id}}
end
def #{method}_id()
#{method}.id
end
def #{method}=(value)
return if value.blank?
value = FeatureOption.find(value) if value.class == String
or value.class == Fixnum
features.delete #{method}
@#{method} = value
self.features << @#{method}
end
def #{method}_id=(value)
self.#{method} = value
end
def #{method}_options
# Тук съм добавил малко код в models/feature.rb, подобен на този горе,
който ми позволява да взимам отделните features "именувани", направо
от класа.
Feature.#{method}.options
end
METHODS
end # each char
end # self.included
end
(Имах неблагоразумието наместо Feature първо да го кръстя
Characteristic, което е трудно и гадно за писане, сега ме мързи да го
преименувам).
class User < ActiveRecord::Base
include Features
end
Tуйто. Сега юзъра вече има закачен метод smoker, smoker=, външно
изглежда като belongs_to. Ако добавя нов feature, ще се наложи да
рестартирам сървъра.
Носи си недостатъци, но чревно го усещам, че май е най-малката злина
за момента. Да видим...
Какво милите?
On Mar 5, 10:44 am, "Stefan Kanev" <
stefan.ka...@gmail.com> wrote:
> *Искаш ли да може потребителя да добавя нови фичъри или само да променя
> тяхните стойности?
> *
>
> - *Не.* В този случай, това е някак класическо. Създаваш таблица за
> всеки фийчър и предлагаш опции за редакцията им в админ панела (ала
> номенклатура). Всеки потребител има по една колонка за фийчър (hookah_id,
> smoking_id) и т.н. Понеже контролерите на всички ще са еднакви, би
> трябвало да е сравнително простичко да направиш нещо като scaffold :hookah и
> така да спестиш повторение на контролер код. С малко въображение, може да
> спестиш доста код. Очевидно програмиста ще добавя фийчъри ръчно, като може
> да се напишат migration helper-и които да улесняват това допълнително -
> add_feature :hookah, вместо create_table :hookah ...; add_column :users,
> :hookah_id. Това ако фичърите се променят средно често или по-рядко. Ако се
> променят сравнително често,
> - *Да.* В този случай бих тръгнал с идеята на Сава и бих добавил код,
> който всъщност бара схемата на базата данни. Това е нещо от което не би
> трябвало да те е страх.
>
> В *никакъв* случай не бих тръгнал с entity-attribute-value антипатерна