2009-10-11 10 views
6

Chcę obsługiwać dwa rodzaje globalnych ustawień konfiguracyjnych:Jaki jest najlepszy sposób przechowywania globalnych ustawień aplikacji w aplikacji Rails?

  • Ustawienia, które mogą być zmieniane przez użytkownika, jak gdyby maile do pewnych zdarzeń są wysyłane lub nie.
  • Ustawienia powiązane z określoną wersją produktu, np. Wyłączenie funkcji w bezpłatnej wersji, która jest dostępna tylko w wersji komercyjnej.

Jaki jest najlepszy sposób przechowywania tych ustawień? Baza danych, plik konfiguracyjny, zakodowany na stałe w źródle, ...?

Odpowiedz

6

W obu przypadkach baza danych. Będziesz używać tych samych struktur dla wielu osób/produktów, więc ma to sens. Pozwala także na zmianę rzeczy bez restartowania serwera.

Zrobiłem to w ten sposób w przeszłości: Dla ustawień specyficznych dla użytkownika, stworzyłem model/tabelę UserSettings, która ma związek jeden do jednego z relacją z użytkownikiem. Rozumowanie tego jest takie, że większość moich operacji z udziałem użytkowników nie wymaga załadowania tych ustawień, więc są one uwzględniane tylko w przypadku obciążeń użytkownika z bazy danych, kiedy ich potrzebuję.

Kiedy to zrobię, zazwyczaj zgrupuję nazwy kolumn, aby móc pisać pomocników, którzy dynamicznie tworzą na podstawie nazw. Oznacza to, że nie będę musiał modyfikować moich widoków, aby włączyć nowe ustawienia, chyba że dodaję jeden z innym schematem nazywania.

Dla ustawień właściwych dla produktu, zależy to od tego, jak to się robi. Istnieje kilka sposobów na zinterpretowanie pytania.

Sposób, w jaki to czytam, polega na tym, że chcesz decydować o poziomie produktu. Jakie ustawienia użytkownicy mogą przesłonić lub wyłączyć ustawienie użytkownika. I ewentualnie zdefiniuj niektóre ustawienia specyficzne dla produktu.

Chciałbym użyć jednego do wielu produktów do ustalenia relacji. Tabela ustawień byłaby czymś prostym (product_id, setting_name, setting_default_value, allow_user_change)

To robi wiele rzeczy. Pozwala na posiadanie zmiennej listy ustawień dla różnych produktów (idealne rozwiązanie w przypadku, gdy oferujesz wiele różnych produktów zamiast zmieniać poziomy dostępu do usług). Pozwala także określić, jakie ustawienia użytkownik może/nie może zmienić i podać wartości dla tego typu produktu. Można to zmienić z poziomu widoku administratora bez ponownego uruchamiania aplikacji. Nie jest również powiązany z ustawieniami użytkownika, do tego stopnia, że ​​jeśli użytkownik nie ma ustawienia wymienionego w ustawieniach produktu, nie będzie żadnych problemów.

Wadą jest to, że w tej tabeli będzie wiele wspólnych ustawień. Przenieślibym ustawienia, że ​​każdy produkt będzie miał inną wartość niż pole w tabeli produktów.

Będziesz musiał również napisać sprawdzanie poprawności, aby upewnić się, że użytkownik nie zmienia ustawienia, którego produkt mówi, że nie może. Będziesz musiał również napisać metody pomocnicze, aby scalić ustawienia od strony produktu i użytkownika.

0

Oto moje doświadczenie z tego rodzaju rzeczy: nie przesłonić zachowania.

Widzisz, twoją pierwszą myślą będzie coś takiego:

Hmm .... Są to ustawienia dla całego systemu, które mogą lub nie mogą być zastąpione przez użytkowników (lub produktów). Hej! Wiem to! To jest kompozycja!

Technicznie, masz rację. Przygotuj tabelę ustawień i umieść tam wszystkie swoje ustawienia. A potem będziesz miał tabelę ustawień użytkownika, gdzie zastąpisz te ustawienia, jeśli tak zdecydujesz. I będzie działać dobrze.

Do momentu dodania ustawienia do jednej tabeli, a nie do drugiej.

Lub pojawia się błąd, że ustawienie X nie może zostać przesłonięte na poziomie użytkownika lub produktu, a wykrycie, gdzie to ustawienie jest ustawione, zajmuje więcej niż 5 sekund.

A potem będziesz sobie sprawę:

Hej, jestem śledzenie wszystkich tych ustawień w co najmniej dwóch różnych miejscach. Wydaje się to trochę głupie.

I będziesz miał rację.

Tak, tak. Śmiało i zachować ustawienia w DB, ale zapisać je wyraźnie dla każdego użytkownika lub produktu. Używaj inteligentnych wartości domyślnych podczas tworzenia wierszy, dzięki czemu wszystko będzie przyjemne i proste.

+1

Podałeś różne założenia dotyczące tego, co on myśli i jak zamierza to zaimplementować, ale jego prawdziwe pytanie brzmiało: "Jaki jest najlepszy sposób przechowywania tych ustawień?" Żadne z twoich założeń nie ma sensu w tym kontekście. Nie sądzę, że to całkiem kwalifikuje się jako "słomkowy człowiek", ale nie jestem pewien, jak inaczej to nazwać. –

0

Dla pierwszego rodzaju ustawień pozostawiłbym je w modelu użytkownika (tabela Użytkownicy).

Drugi rodzaj ustawień ponownie trafiłby do bazy danych. Na przykład, jeśli użytkownik miał darmowe konto, byłoby to w jakiś sposób zapisane w bazie danych. Chciałbym mieć pomocników w aplikacji, na przykład "za darmo"? lub "komercyjne?". Ci pomocnicy mogą dowiedzieć się, czy są one prawdziwe lub fałszywe, pytając o aktualnie podłączony model użytkownika/konta. Następnie możesz użyć tych pomocników w różnych częściach aplikacji, aby zdecydować, czy pokazujesz lub ukrywasz określoną funkcję.

+0

Aby to zrobić, musielibyśmy dokonać denormalizacji. Prawdopodobnie w formie zserializowanego pola ustawień. Niekoniecznie coś złego, ale denormalizacja zawsze jest kompromisem. –

1
class Flag < ActiveRecord::Base 
    # id, user_id, name, value (serialized probably) 

    belongs_to :user 

    DEFAULTS = { 
    "newsletter" => false 
    } 

    def self.lookup(user, flag) 
    # Please involve memcached here 
    case flag 
    when "ssl_enabled" 
     # Check if user has paid for sufficient access to SSL 
     return false 
    else 
     stored_flag = self.find_by_user_id_and_name(user.id, flag) 
     if stored_flag 
     return stored_flag.value 
     else 
     return DEFAULTS[flag] 
     end 
    end 
    end 
end 

class User < ActiveRecord::Base 
    has_many :flags 

    def flag(name) 
    return Flag.lookup(self, name) 
    end 
end 

Do rzeczy, które edycja produkt na bazie, to pewnie nie może naprawdę przechowywać rzeczy w bazie danych, ponieważ flaga ma być oparte na jakimś kawałku kodu autoryzacyjnego, zamiast danych statycznych.

Powiązane problemy