2011-11-16 7 views
15

मेरे पास वर्तमान में एक मॉडल है जिसमें एक स्टेटस कॉलम होगा, और इस स्थिति कॉलम के लिए केवल कुछ मान होंगे। STATUS_OPTIONS = {: yes,: no,: शायद}मैं रेल में enum निर्दिष्ट और मान्य कैसे करूं?

1) मुझे यकीन नहीं है कि उपयोगकर्ता उपस्थित होने से पहले मैं इसे कैसे सत्यापित कर सकता हूं? मूल रूप से जावा में एक enum लेकिन मैं रेल में यह कैसे कर सकता है?

+0

म्यू और माइक के जवाब अच्छे हैं - यह भी http://stackoverflow.com/q/265725/887124 देखते हैं, जो देता है एक समान प्रश्न के कुछ अलग जवाब। –

+0

हाँ, मैं वास्तव में समाधान बॉब द्वारा प्रदान किए गए कुछ और समान उपयोग करता हूं: [gist] (https://gist.github.com/1372650) – mnelson

उत्तर

26

इच्छित विकल्पों तक पहुँच सुलभ सरणी बनाएं, फिर मान्य अपनी स्थिति स्तंभ के मूल्य:

class Attend < ActiveRecord::Base 

    STATUS_OPTIONS = %w(yes no maybe) 

    validates :status, :inclusion => {:in => STATUS_OPTIONS} 

end 

फिर आप Attend::STATUS_OPTIONS

+5

प्री रेल 4.1 यह ठीक है। रेल में 4.1+ अंतर्निर्मित enums का उपयोग करें: http://edgeguides.rubyonrails.org/4_1_release_notes.html#active-record-enums – mnelson

+1

रेल में "मूल" enums का उपयोग 4.1 में postgresql में वास्तव में देशी enums का उपयोग करने की समान कमी है। आपको वास्तविक आदेश का ख्याल रखना होगा, आप एक बार बनाए गए एनम को आसानी से संशोधित नहीं कर सकते हैं। इसके अलावा, "मूल" रेल के साथ, यह एक टूटी हुई विशेषता है, क्योंकि एक तरफ आप उन्हें लिखते हैं और उन्हें डंक के रूप में पढ़ते हैं, लेकिन दूसरी ओर आपको उन्हें संख्याओं के रूप में पूछने की आवश्यकता है। कम से कम postgresql के enums के साथ, डेटाबेस से बाहर सबकुछ तारों को देखेंगे। – rewritten

+0

enum काम पाने की कोशिश कर रहे एक घंटे के लिए संघर्ष करने के बाद, यह समाधान कहीं अधिक दिलचस्प है, और इसमें कोई कमी नहीं है - Enum के लिए ऐसा नहीं कह सकता है। –

4

आप सुनिश्चित करें कि आप केवल आप क्या उम्मीद कर रहे हैं पाने के बनाने के लिए :inclusion option for validates की स्थिति के लिए एक स्ट्रिंग स्तंभ इस्तेमाल कर सकते हैं और उसके बाद:

class Attend < ActiveRecord::Base 
    validates :size, :inclusion => { :in => %w{yes no maybe} } 
    #... 
end 
45
अब

किके माध्यम से संभावित स्थितियां यहां पहुंच सकता हैenums निम्नलिखित आप कर सकते हैं शामिल हैं:

class Attend < ActiveRecord::Base 
    enum size: [:yes, :no, :maybe] 
    # also can use the %i() syntax for an array of symbols: 
    # %i(yes no maybe) 
    validates :size, inclusion: { in: sizes.keys } 
end 

जो फिर एक गुंजाइश प्रदान करता है (यानी: Attend.yes, Attend.no, Attend.maybe प्रत्येक एक चेकर विधि के लिए करता है, तो निश्चित स्थिति सेट कर दिया जाता है देखने के लिए (यानी: #yes?, #no?, #maybe?), विशेषता सेटर विधियों के साथ (यानी: #yes!, #no!, #maybe!)।

Rails Docs on enums

+4

जो मैं पढ़ रहा हूं उससे रेल के मौजूदा कार्यान्वयन आंतरिक मूल्यों के लिए हैं और उपयोगकर्ताओं को उजागर करने के लिए नहीं, क्योंकि सवाल पूछा गया है (जो मुझे लगता है कि शर्म की बात है)। मैं इसे 14 फरवरी से निम्नलिखित धागे से प्राप्त कर रहा हूं। Https://github.com/rails/rails/issues/13971 –

+2

इसे प्यार करें। नया सर्वोत्तम अभ्यास, आईएमओ। –

2

हम क्या कर रही एक सरणी के भीतर हमारे enum आइटम को परिभाषित किया जाता है और फिर enum, सत्यापन का उल्लेख करते समय और आवेदन के भीतर मानों का उपयोग के लिए है कि सरणी का उपयोग शुरू कर दिया है।

STATUS_OPTIONS = [:yes, :no, :maybe] 
enum status_option: STATUS_OPTIONS 
validates :status_option, inclusion: { in: STATUS_OPTIONS.map {|t| t.to_s } } 

इस तरह आप भी बाद में STATUS_OPTIONS उपयोग कर सकते हैं, सूची एक ड्रॉप डाउन बनाने के लिए की तरह। आप उपयोगकर्ता के लिए अपने मूल्यों को बेनकाब करना चाहते हैं तो आप हमेशा इस तरह मैप कर सकते हैं:

STATUS_OPTIONS.map {|s| s.to_s.titleize } 
8

उपयोग कर सकते हैं इस तरह मैं अपने रेल में 4 परियोजना को लागू है।

class Attend < ActiveRecord::Base 
    enum size: [:yes, :no, :maybe] 
    validates :size, inclusion: { in: Attend.sizes.keys } 
end 

Attend.sizes आपको मैपिंग देता है।

Attend.sizes # {"yes" => 0, "no" => 1, "maybe" => 2} 

See more in Rails doc

+6

अनिवार्य रूप से वही टिप्पणी [यह एक] (http://stackoverflow.com/questions/8146965/how-do-i- स्पेसिफी-and-validate-an-enum-in-rails/8147002#comment42094863_26365696), लेकिन यह काम नहीं करेगा, क्योंकि प्रमाणीकरण कहने से पहले, enum विशेषताएँ अमान्य मानों पर अमान्य अर्ग्यूमेंट अपवाद फेंक देंगे। उस पर और अधिक: https://github.com/rails/rails/issues/13971 –

+0

@Koen। सही है मैंने इस समाधान की कोशिश की और 'ArgumentError' के साथ समाप्त हो गया। –

0

कुछ देखने के बाद, मैं नहीं एक एक लाइनर मॉडल में यह हो मदद करने के लिए मिल सकता है। अब तक, रेल Enums प्रदान करता है, लेकिन अमान्य मान मान्य करने के लिए एक व्यापक तरीका नहीं है।

इसलिए, मैंने एक समग्र समाधान का चयन किया: strong_params सेट करने से पहले, और फिर मॉडल के विरुद्ध जांच करके नियंत्रक में एक सत्यापन जोड़ने के लिए।

में भाग लेने:

तो, मॉडल में, मैं एक विशेषता और एक कस्टम सत्यापन पैदा करेगा।rb

enum :status => { your set of values } 
attr_accessor :invalid_status 

validate :valid_status 
#... 
private 
    def valid_status 
     if self.invalid_status == true 
      errors.add(:status, "is not valid") 
     end 
    end 

इसके अलावा, मैं अमान्य इनपुट के लिए मानकों के खिलाफ एक जांच करेंगे और (यदि आवश्यक हो) मॉडल के लिए परिणाम भेजने के लिए, तो एक त्रुटि वस्तु में जोड़ दिया जाएगा, इस प्रकार यह अवैध

बनाने

attends_controller.rb

private 
    def attend_params 
     #modify strong_params to include the additional check 
     if params[:attend][:status].in?(Attend.statuses.keys << nil) # to also allow nil input 
      # Leave this as it was before the check 
      params.require(:attend).permit(....) 
     else 
      params[:attend][:invalid_status] = true 
      # remove the 'status' attribute to avoid the exception and 
      # inject the attribute to the params to force invalid instance 
      params.require(:attend).permit(...., :invalid_status) 
     end 
    end 
संबंधित मुद्दे