2016-06-10 9 views
6

मैं फीनिक्स/एलिक्सीर के लिए वास्तव में नया हूं और मैं अपने सिर को बदलावों के चारों ओर लपेटने की कोशिश कर रहा हूं।रेपो में डालने से पहले एक एक्टो चेंजेट को कैसे संशोधित करें?

मुझे लगता है कि इसमें परिवर्तनों का एक सेट है जो मॉडल बनाने या अपडेट करने के लिए उपयोग किया जाता है।

मैं क्या जानना चाहता हूं कि डेटाबेस में इसे धक्का देने से पहले मैं और कैसे परिवर्तन को संशोधित कर सकता हूं।

  • मैं एक रूप है कि लोगों को डेटाबेस में नए कलाकारों को बनाने की अनुमति है:

    मेरे उपयोग के मामले निम्नलिखित है।

  • इस रूप में एक विशेषता क्षेत्र है।
  • कलाकार बनाने से पहले, मैं स्ट्रिंग

की एक सरणी मैं अचल स्थिति की कमी के कारण भी यकीन है कि सीधे changeset संशोधित करके यह संभव है नहीं कर रहा हूँ के रूप में यह स्टोर करने के लिए द्वारा विशेषता क्षेत्र विभाजित करना चाहते हैं "," लेकिन मैं रेपो में सम्मिलित करने के लिए शायद एक अन्य बदलाव बना सकता हूं।

कोई भी सुझाव स्वागत है और खराब प्रथाओं या बेवकूफ चीजों को इंगित करने में संकोच नहीं करते हैं जो मैं कर सकता हूं!

संपादित करें टिप्पणी निम्नलिखित: मैं की तरह कुछ में देख रहा हूँ:

defp put_specialty_array(changeset) do 
    case changeset do 
    %Ecto.Changeset{valid?: true, changes: %{specialty: spec}} -> 
     put_change(changeset, :specialty, String.split(spec, ",")) 
    _ -> 
     changeset 
    end 
end 
+0

यह उपयोगकर्ता के पासवर्ड को हश करने और संग्रहीत करने के लिए एक समान दृष्टिकोण है। जांचें कि कैसे ["प्रोग्रामिंग फीनिक्स"] (https://pragprog.com/book/phoenix/programming-phoenix) ने इसे किया [यहां] (https://media.pragprog.com/titles/phoenix/code/authentication/listings /rumbl/web/models/user.change1.ex)। defp put_specialty_array (changeset) मामले करना ChangeSet % Ecto.Changeset {वैध ?: सच है, परिवर्तन कार्य करें::% {विशेषता: कल्पना (विशेष रूप से कैसे '' registration_changeset' बुला रहा है put_pass_hash') – AbM

+0

तो मैं कुछ ऐसा कर सकता है }} -> put_change (changeet,: विशेषता, String.split (spec, ",")) परिवर्तन अंत अंत ? – Cratein

+0

आपके सुझाव को थोड़ा सा – AbM

उत्तर

9

मेरा मानना ​​है कि क्या आप देख रहे हैं एक कस्टम Ecto.Type है। मैं यह हर समय करता हूं, और यह बहुत अच्छा काम करता है! यह कुछ इस तरह दिखेगा:

defmodule MyApp.Tags do 
    @behaviour Ecto.Type 
    def type, do: {:array, :string} 
    def cast(nil), do: {:ok, nil} # if nil is valid to you 
    def cast(arr) when is_list(arr) do 
    if Enum.all?(arr, &String.valid?/1), do: {:ok, arr}, else: :error 
    end 
    def cast(str) when is_binary(str), do: {:ok, String.split(",")} 
    def cast(_), do: :error 

    def dump(val) when is_list(val), do: {:ok, val} 
    def dump(_), do: :error 
    def load(val) when is_list(val), do: {:ok, val} 
    def load(_), do: :error 
end 

फिर अपने प्रवास में, किसी स्तंभ सही प्रकार

add :tags, {:array, :string} 

साथ अंत में अपने स्कीमा में आपके द्वारा बनाए गए क्षेत्र के प्रकार का उल्लेख जोड़ें।

field :tags, MyApp.Tags 

फिर आप इसे अपने परिवर्तन में एक फ़ील्ड के रूप में जोड़ सकते हैं। यदि आपके प्रकार का कास्ट :error देता है, तो परिवर्तन में {:tags, ["is invalid"]} जैसी कोई त्रुटि होगी। आपको अपने मॉडल या नियंत्रक में फ़ील्ड की किसी भी प्रसंस्करण के बारे में चिंता करने की ज़रूरत नहीं है। यदि उपयोगकर्ता मान के लिए स्ट्रिंग सरणी पोस्ट करता है या केवल अल्पविराम से अलग स्ट्रिंग पोस्ट करता है, तो यह काम करेगा।

आप एक अलग स्वरूप में डेटाबेस के लिए मूल्य को बचाने के लिए की जरूरत है, तो आप सिर्फ def type के रिटर्न मान बदल सकते हैं और यह सुनिश्चित करें कि def dump उस प्रकार के मान देता है और उस def load को उस प्रकार के एक मूल्य पढ़ सकते हैं जो कुछ भी आंतरिक प्रतिनिधित्व आप चाहते हैं। एक आम पैटर्न आंतरिक प्रतिनिधित्व के लिए एक संरचना को परिभाषित करना है ताकि आप जहर के to_json का अपना कार्यान्वयन कर सकें जो एक साधारण स्ट्रिंग भी लौटा सकता है। एक उदाहरण लैट्लिंग प्रकार हो सकता है जो जेसन में 12.12345N,123.12345W पर पोस्ट करता है, पोस्टग्रेज़ में कुछ जीआईएस प्रकार के रूप में स्टोर करता है, लेकिन %LatLng{lat: 12.12345, lng: -123.12345} जैसी संरचना है जो आपको एलिक्सीर में कुछ सरल गणित करने देती है। डेटटाइम प्रारूप इस तरह बहुत काम करते हैं (एलिक्सीर के लिए एक संरचना है, डीबी ड्राइवर के लिए एक ट्यूपल प्रारूप और जेसन के लिए एक आईएसओ प्रारूप)।

मुझे लगता है कि यह पासवर्ड फ़ील्ड, बीटीडब्ल्यू के लिए वास्तव में अच्छा काम करता है।आप जेएसओएन प्रतिनिधित्व को स्क्वैश कर सकते हैं, एल्गोरिदम का प्रतिनिधित्व करने के लिए एक स्ट्रक्चर का उपयोग कर सकते हैं, हैश से एल्गोरिदम अलग नमक के पैरामीटर या जो भी जीवन आसान बनाता है। अपने कोड में, पासवर्ड अपडेट करने के लिए, यह केवल Ecto.Changeset.change(user, password: "changeme") होगा।

मुझे एहसास है कि यह 6mo पुराना प्रश्न है और आपको शायद कुछ मिल गया है, लेकिन मैं यहां Google खोज से समाप्त हुआ, और दूसरों को भी मान लेता हूं।

+0

क्या आप जानते हैं कि वर्तमान उपयोगकर्ता के प्रासंगिक डेटा को कस्टम फ़ील्ड में इंजेक्ट करने का कोई तरीका है या नहीं? उस मामले में कहें जहां मैं उपयोगकर्ता की पासफ्रेज़ कुंजी का उपयोग करके फ़ील्ड को एन्क्रिप्ट/डिक्रिप्ट करना चाहता हूं और कस्टम फ़ील्ड के भीतर से कुंजी को संदर्भित करने की आवश्यकता है। –

संबंधित मुद्दे