रेलिंग 4.1 में चयन से एनम की बचत


108

मैं शराब के रंगों का ट्रैक रखने के लिए रेल्स 4.1 में एनम का उपयोग कर रहा हूं।

Wine.rb

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

मेरे विचार में, मैं एक चयन करता हूं ताकि उपयोगकर्ता एक निश्चित रंग के साथ शराब का चयन कर सके

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

यह निम्न 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>

हालाँकि, फॉर्म सबमिट करने पर, मुझे एक तर्क त्रुटि बताते हुए कहा गया है '1' is not a valid color। मुझे इस बात का एहसास है क्योंकि colorसमान होना चाहिए 1और नहीं भी "1"

वहाँ एक स्ट्रिंग के बजाय एक पूर्णांक के रूप में रंग की व्याख्या करने के लिए रेल को मजबूर करने का एक तरीका है?

जवाबों:


203

ठीक है, इसलिए स्पष्ट रूप से, आपको सहेजे जाने वाले एनम के पूर्णांक मान को नहीं भेजना चाहिए। आपको एनम का पाठ मान भेजना चाहिए।

मैंने निम्नलिखित होने के लिए इनपुट बदला:

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

जो निम्न 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>

मान "0" से "लाल" तक चला गया और अब हम सभी सेट हैं।


यदि आप एक नियमित राजभाषा 'रेल का उपयोग कर रहे हैं तो यह करें:

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


यदि आप स्वच्छ मानव-पठनीय विशेषता रखना चाहते हैं, तो आप यह भी कर सकते हैं:

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


8
एफडब्ल्यूआईडब्ल्यू, मुझे इसे बनाने की आवश्यकता थी f.select :color, Wine.colors.to_a.map { |w| [w[0].humanize, w[0]] }क्योंकि wएक सरणी का प्रतिनिधित्व किया। यकीन नहीं क्यों, लेकिन शायद यह किसी की मदद करेगा।
जकलबीब

titleizeयदि आपके पास दो या दो से अधिक शब्द हैं
अनवर

8
keysविधि एक सरणी देता है ताकि to_aअनावश्यक है। वैकल्पिक रूप से चयनित सहायक विधि विकल्पों के लिए एक 2 डी सरणी लेती है ताकि आप बस उपयोग कर सकें to_a
xander-miller

क्या होगा यदि कोई अमान्य स्ट्रिंग "ERROR_JUNK_Submission" जैसे भेजा जाता है। जाहिर है कि इस तरह के रूप में कोई एनम मूल्य नहीं है, और एक अपवाद फेंक दिया गया है। हम इसे कहां से पकड़ेंगे?
फ्लाइंगवी नोव

मॉडल वाइन में एक enum color: [:red, :white, :sparkling]f.input :color, :as => :select, :collection => Wine.color.keys.to_a
एनुम

32

एनम हैश को सरणी के साथ परिवर्तित करने की आवश्यकता नहीं है to_a। यह पर्याप्त:

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

10

मैंने अभी एक EnumHelper को एक साथ रखा था, जो मुझे लगा कि मैं उन लोगों की मदद करने के लिए साझा करूँगा जिन्हें आपके enum selects के लिए अधिक अनुकूलित 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.underscore}.#{enum}.#{key}"), key]
    }
  end

end

अपने स्थान पर:

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

आपके विचारों में:

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

1
संपादित करें अनुवाद कुंजियों को मल्टीवॉर्डक्लासनाम के बजाय कई विशिष्ट
एकाधिक_शब्द_क्लास_नाम के

कैसे एक सुंदर कमबैक के लिए एक डिफ़ॉल्ट में जोड़ने के बारे में: [I18n.t("activerecord.enums.#{klass.underscore}.#{enum}.#{key}", default: key.humanize), key] इसके अलावा, अंतिम हटा दें humanizeक्योंकि यह पूंजीकरण को विकृत कर सकता है यदि इसके कई शब्द
पीटर पी।

9

स्वीकृत समाधान मानव पठनीय के लिए मेरे काम नहीं आया , लेकिन मैं इसे इस तरह काम करने में सक्षम था:

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

यह सबसे साफ था, लेकिन मुझे वास्तव में अपनी चाबी को मानवीय बनाने की जरूरत थी:

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

1
रेल 5 अब सबसे साफ तरीके का समर्थन करता है
V-SHY

@ वी-SHY, यह तरीका क्या है, क्या आप समझा सकते हैं?
इमेलारिलिक

2
@ismailarilik, सीधे चयन विकल्प के रूप में कुंजियाँ प्रदान करता है, <% = f.select (: color, Wine.colors.keys)%>
V-SHY

6

यदि आप रेल 4 में एनम का उपयोग करते हैं तो कॉल करें Model.enums:

f.select :color, Wine.colors.keys

HTML बनाने के लिए:

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

या नियंत्रक में विधि जोड़ें:

def update_or_create
    change_enum_to_i
    ....
end

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

4

यहाँ मेरे लिए काम किया है, रेल 4+:

class Contract < ApplicationRecord

enum status: { active:  "active", 
               ended: "active", 
               on_hold: "on_hold", 
               terminated:  "terminated", 
               under_review:  "under_review" , 
               unknown: "unknown" 
              }


end

में my _form.html.erb, मेरे पास यह है:

  <div class="field">
    <%= form.select :status, Contract.statuses.keys, {}%>
  </div>

रिकॉर्ड जोड़ने के बाद कंसोल से परीक्षण:

2.3.0 :001 > Contract.last.status
  Contract Load (0.2ms)  SELECT  "contracts".* FROM "contracts" ORDER BY "contracts"."id" DESC LIMIT ?  [["LIMIT", 1]]
 => "active"

3

यदि आपको i18n को एनम कीज़ के आधार पर संभालने की आवश्यकता है, जिसका आप उपयोग कर सकते हैं:

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

और tranlations में आप रंग सेट कर सकते हैं:

wine:
 red: Red
 white: White

1

यहाँ मेरा समाधान है (मेरी भूमिकाओं में उन्हें "sales_rep" की तरह रेखांकित किया गया है), और किसी कारण से मुझे काम करने के लिए एक खाली विकल्प प्राप्त करने की आवश्यकता थी (साधारण से?)

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

फिर मेरे रूप में:

<%= f.input :role, collection: enum_collection_for_select(User.roles), selected: @user.role %>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.