2014-05-15 17 views
87

Używam enums w Rails 4.1, aby śledzić kolory wina.Zapisywanie enum z select w Rails 4.1

Wine.rb

class Wine < ActiveRecord::Base 
    enum color: [:red, :white, :sparkling] 
end 

Moim zdaniem wygenerować wybierz więc użytkownik może wybrać wino z określonego koloru

f.input :color, :as => :select, :collection => Wine.colors 

To generuje następujący kod HTML:

<select id="wine_color" name="wine[color]"> 
    <option value=""></option> 
    <option value="0">red</option> 
    <option value="1">white</option> 
    <option value="2">sparkling</option> 
</select> 

Jednak po przesłaniu formularza otrzymuję n Błąd argumentu podając '1' is not a valid color. Rozumiem, że to dlatego, że color musi być równy 1, a nie "1".

Czy istnieje sposób zmuszenia Railsów do interpretowania koloru jako liczby całkowitej zamiast łańcucha?

Odpowiedz

168

W porządku, więc najwyraźniej nie należy wysyłać wartości całkowitej enum do zapisania. Powinieneś wysłać wartość tekstową wyliczenia.

Zmieniłem wkład następujące:

f.input :color, :as => :select, :collection => Wine.colors.keys.to_a

który wygenerował następujący kod HTML:

<select id="wine_color" name="wine[color]"> 
    <option value=""></option> 
    <option value="red">red</option> 
    <option value="white">white</option> 
    <option value="sparkling">sparkling</option> 
</select> 

wartości przeszedł od "0" do "czerwony", a teraz jesteśmy Wszystko gotowe.


Jeśli używasz szyny regularnej Ol”text_field to:

f.select :color, Wine.colors.keys.to_a


Jeśli chcesz mieć czyste atrybuty czytelny dla człowieka można również zrobić:

f.select :color, Wine.colors.keys.map { |w| [w.humanize, w] }

+1

Dzięki za to, rozwiązać mój problem. Pamiętaj jednak, że w ostatniej edycji brakuje '}'. – henrebotha

+1

ah @henrebotha dobry połów. zaktualizowany. –

+0

Próbowałem wszystkich rodzajów opcji. Ten naprawdę działa. Dziękuję Ci! – Hendrik

18

Nie trzeba konwertować e liczba hash do tablicy z to_a. To wystarczyć:

f.select :color, Wine.colors.map { |key, value| [key.humanize, key] } 
5

właśnie ułożyła EnumHelper że myślałem, że dzielić, aby pomóc ludziom, którzy potrzebują bardziej spersonalizowanych etykiet enum i lokalizacji dla swoich wybiera enum.

module EnumHelper 

    def options_for_enum(object, enum) 
    options = enums_to_translated_options_array(object.class.name, enum.to_s) 
    options_for_select(options, object.send(enum)) 
    end 

    def enums_to_translated_options_array(klass, enum) 
    klass.classify.safe_constantize.send(enum.pluralize).map { 
     |key, value| [I18n.t("activerecord.enums.#{klass.downcase}.#{enum}.#{key}").humanize, key] 
    } 
    end 

end 

W danym regionie:

en: 
    activerecord: 
    enums: 
     wine: 
     color: 
      red: "Red Wine" 
      white: "White Wine" 

w widokach:

<%= f.select(:color, options_for_enum(@wine, :color)) %> 
0

Jeśli używasz enum w Rails 4 następnie zadzwoń Model.enums:

f.select :color, Wine.colors.keys 

Aby utworzyć HTML:

<select name="f[color]" id="f_color"> 
    <option value="red">red</option> 
    <option value="white">white</option> 
    <option value="sparkling"> sparkling </option> 
</select> 

Albo dodać metody w kontrolerze:

def update_or_create 
    change_enum_to_i 
    .... 
end 

def change_enum_to_i 
    params[:f]["color"] = params[:f]["color"].to_i 
end 
1

Oto moje rozwiązanie (moje role mają podkreślenia w nich jak „sales_rep”), iz jakiegoś powodu to było jak ja potrzebowałem dostać pustą opcję do pracy (z simpleform):

w ApplicationHelper:

def enum_collection_for_select(attribute, include_blank = true) 
    x = attribute.map { |r| [r[0].titleize, r[0]] } 
    x.insert(0,['', '']) if include_blank == true 
    x 
end 

potem w moim formularzu:

<%= f.input :role, collection: enum_collection_for_select(User.roles), selected: @user.role %> 
6

Przyjęte rozwiązanie nie działa dla mnie za czytelnej, ale udało mi się zmusić go do pracy tak:

<%= f.select(:color, Wine.colors.keys.map {|key| [key.humanize, key]}) %> 

To był najczystszy, ale naprawdę potrzebne do uczłowieczyć moje klucze:

<%= f.select(:color, Wine.colors.keys) %> 
+0

szyny 5 obsługuje najczystszy sposób teraz –

+0

@ V-SHY, co to jest, czy możesz wyjaśnić? – ismailarilik

+1

@ismailarilik, bezpośrednio podaj klucze jako opcję zaznacz, <% = f.select (: color, Wine.colors.keys)%> –

2

Jeśli trzeba obsłużyć i18n oparty na klawiszach enum można użyć:

<%= f.select :color, Wine.colors.keys.map {|key| [t("wine.#{key}"), key]} %> 

aw tranlations można ustawić kolory:

wine: 
red: Red 
white: White 
Powiązane problemy