2013-07-04 21 views
20

biegnę Rails 4.dostępu w widoku Rails

mam model o nazwie Challenge, aw mojej bazy danych mam przechowywania status każdego wyzwania w zakresie 0-4.

Ale 0-4 nie jest bardzo semantyczne więc chcę, aby zdefiniować kilka zmiennych (Jestem przy założeniu stałych), tak, że w każdym kontrolerze lub zobacz mogę uzyskać dostęp do numeru dzwoniąc stała:

# Challenge.rb 
class Challenge < ActiveRecord::Base 
    SUGGESTED = 0 
    APPROVED = 1 
    OPEN = 2 
    VOTING = 3 
    CLOSED = 4 
end 

Chcę uzyskać dostęp do nich moim zdaniem:

# challenge/_details.html.erb 
<% if @challenge.status == CLOSED %> 
    Challenge is closed, broheim! 
<% end %> 

Ale moim zdaniem nie chce uczynić.

uninitialized constant ActionView::CompiledTemplates::CLOSED 

Jaki jest najlepszy sposób na ustawienie zmiennych statusu, aby można było uzyskać do nich dostęp wszędzie, gdzie ich potrzebuję? (Czyli wszędzie zmienna @challenge jest obecny)

+2

polecam używać Hash jako stała w tym przypadku. Czemu? Ponieważ zmniejszy to liczbę różnych stałych modelu. Coś jak: 'STATUSES = {proponowane: 0, zatwierdzone: 1, otwarte: 2, itd: ..}' i dostęp do niego jak 'Wyzwanie :: STATUSES.approved' – MrYoshiji

Odpowiedz

41

Należy do nich dostęp w następujący sposób:

Challenge::CLOSED 

Ponieważ stała CLOSED jest zdefiniowana w obrębie klasy, trzeba uzyskać dostęp do stałej za pomocą operatora rozdzielczość zakres. Więc jeśli Państwa zdaniem byłoby sprawdzić to lubią:

# challenge/_details.html.erb 
<% if @challenge.status == Challenge::CLOSED %> 
    Challenge is closed, broheim! 
<% end %> 
+1

To trochę zbędne, biorąc pod uwagę, że moje instrukcje if już się odwołują zmienna @challenge. Czy istnieje sposób, aby to zrobić tak semantycznie, że brzmi jak angielski? – alt

+0

Hej thanx to jest dla mnie bardzo przydatne. –

9

To bardzo zły pomysł, aby zakodować tego rodzaju stwierdzeń: Twój obiekt musi obsługiwać własną logikę. Wyobraź sobie, że jeśli pewnego dnia zdecydujesz się scalić status, czy zmienisz wszystkie warunki warunkowe w swojej bazie? Nie, powinieneś użyć jednej metody, która obsługuje logikę.

bym wykonać następujące czynności:

class Challenge < ActiveRecord::Base 
    SUGGESTED = 0 
    APPROVED = 1 
    OPEN = 2 
    VOTING = 3 
    CLOSED = 4 

    #defines: 
    # - suggested? 
    # - approved? 
    # - ... 
    %w(suggested approved open voting closed).each do |state| 
    define_method "#{state}?" do 
     status == self.class.const_get(state.upcase) 
    end 
    end 

    #if you prefer clarity, define each method: 

    def suggested? 
    status == SUGGESTED 
    end 

    #etc... 
end 

Następnie w widoku:

<% if @challenge.closed? %> 
+0

Nie wydaje się bardzo semantyczna. Jest to także dość myląca ilość kodu, który można znaleźć w modelu projektu open source. Może mógłbyś wyjaśnić, dlaczego idea @ MrYoshiji jest tak bardzo zła? – alt

+2

Nie ma nic wielkiego do tworzenia metod, jeśli mają sens, znacznie lepiej niż logikę wewnętrzną poza modelem. Pomysł @MrYoshiji jest w porządku. – apneadiving

+0

btw, jak to może być bardziej semantyczne niż "@ challenge.closed?"? – apneadiving

Powiązane problemy