Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

Trix और Turbo Frames का उपयोग करके रेल्स में डायनामिक टेबल एडिटर बनाएं

इस पोस्ट में, हम आपके रेल्स एप्लिकेशन के लिए एक बुनियादी ActionText टेबल एडिटर लागू करेंगे। हम सीखेंगे कि कैसे:

  • ActionText और Trix अटैचमेंट्स को संभालते हैं
  • अपना खुद का Attachable टाइप लागू करें, और इसका लाभ उठाकर एक बुनियादी टेबल एडिटर बनाएं
  • Turbo Frames का उपयोग टेबल को संपादित करने के लिए किया जा सकता है
  • Turbo कैसे मदद करता है और साथ ही रास्ते में आता है

यह लेख 2020 के उत्कृष्ट 'Adding Tables to ActionText With Stimulus.js' ब्लॉग पोस्ट से प्रेरणा लेता है। यह Turbo के आगमन से पहले लिखा गया था, जिससे हम उम्मीद कर सकते हैं कि मामले काफी सरल हो जाएंगे।

चलिए शुरू करते हैं!

रूबी में ActionText अटैचमेंट्स 101

नोट: यह प्रदर्शन Trix और Turbo Frames की कुछ समझ मानता है। आप Hotwire और Turbo Frames की मूल बातें सीखने के लिए हमारे 'Get Started with Hotwire in Your Ruby on Rails App' पोस्ट को उपयोगी पा सकते हैं।

आप इस GitHub रेपो के साथ कोड प्रदर्शन का अनुसरण कर सकते हैं।

ActionText दस्तावेज़ में वर्णित अनुसार:

Action Text रेल्स में रिच टेक्स्ट कंटेंट और संपादन लाता है। इसमें Trix एडिटर शामिल है जो फॉर्मेटिंग से लेकर लिंक्स, कोट्स, लिस्ट्स, एम्बेडेड इमेजेज और गैलरी तक सब कुछ संभालता है।

उच्च स्तर पर, अटैचमेंट्स ActionText के डॉक्यूमेंट मॉडल का हिस्सा हैं। वे किसी भी संसाधन के लिए कस्टम टेम्पलेट्स रेंडर करते हैं जिसे साइन ग्लोबल आईडी (SGID) द्वारा हल किया जा सकता है। दूसरे शब्दों में, ActionText एक निश्चित SGID के संदर्भ को <action-text-attachment> एलिमेंट के रूप में स्टोर करता है:

 

जब भी ActionText ऐसे एलिमेंट का सामना करता है, तो यह संबंधित संसाधन पर to_attachable_partial_path मेथड को कॉल करता है। डिफ़ॉल्ट रूप से, यह मेथड to_partial_path को डेलीगेट करता है।

तो, पूर्वावलोकन के रूप में, जब HTML पर वापस रेंडर किया जाता है तो ActionText में हमारे Table का प्रतिनिधित्व इस तरह दिखेगा:

 

ActionText Attachment API के अनुरूप होने के लिए, एक क्लास को केवल दो चीजें करनी होती हैं:

  1. GlobalID::Identification को शामिल करके to_sgid लागू करें। डिफ़ॉल्ट रूप से, सभी ActiveRecord::Base वंशज पहले से ही ऐसा करते हैं।
  2. ActionText::Attachable मॉड्यूल शामिल करें।

ActionText::Attachable मॉड्यूल किसी भी मॉडल को SGID के माध्यम से और से कैनोनिकल तरीके से परिवर्तित करने के लिए attachable_sgid और from_attachable_sgid मेथड्स प्रदान करता है। हम बाद में इसका उपयोग करेंगे।

यह अटैचमेंट मेटाडेटा के लिए सुविधाजनक एक्सेसर्स भी प्रदान करता है, जैसे फ़ाइल आकार और नाम, साथ ही कंटेंट टाइप।

अंत में, यह एडिटर और रिच टेक्स्ट व्यूज़ में अटैचमेंट को रेंडर करने के लिए उपयोग किए जाने वाले पार्शियल्स के लिए डिफ़ॉल्ट स्थान प्रदान करता है।

टेबल मॉडल जोड़ना

हम ActionText के Attachment API का लाभ उठाकर अपना टेबल समाधान लागू करेंगे। इसके लिए, हमें अपने टेबल्स के डेटा को कैप्चर करने वाला एक कस्टम मॉडल बनाना होगा और Attachable शामिल करना होगा। हम टेबल डेटा के लिए दो-आयामी ऐरे को रखने के लिए एक साधारण JSON(B) कॉलम का उपयोग करेंगे।

हमारी खोज शुरू करने के लिए, आइए ActionText सक्षम के साथ एक नया रेल्स ऐप बनाएं:

 

क्योंकि मैं आज रचनात्मक महसूस नहीं कर रहा हूं, आइए एक Article मॉडल को टाइटल और रिच टेक्स्ट कंटेंट के साथ स्कैफोल्ड करें:

 

सावधान, यहां एक आश्चर्यजनक गड़बड़ है! उपरोक्त इंस्टॉल कमांड ने एक CreateActionTextTables माइग्रेशन बनाया, इसलिए हमें इसका नाम बदलकर CreateActionTextTablesTable करना होगा। इसके अतिरिक्त, हम इसे null: false, default: [["", ""], ["", ""]] का उपयोग करके 2x2 टेबल पर डिफ़ॉल्ट करेंगे।

 

रूबी ActionText मॉडल में टेबल जोड़ें

इससे पहले कि हम वास्तव में रिच टेक्स्ट में टेबल जोड़ना जारी रखें, हमें Trix के टूलबार को पैच करना होगा:

 

यहां, हम मैन्युअली Trix के toolbarElement में एक बटन जोड़ते हैं। इसे एक trix-table Stimulus कंट्रोलर (जिसे हमें अभी बनाना है) से जोड़ने से डॉक्यूमेंट में एक टेबल इन्सर्ट होगा। आइए इस बटन को CSS में एक अच्छा SVG कंटेंट दें और कुछ टेबल स्टाइल सेट करें जबकि हम इस पर हैं:

 

जैसा कि आप देख सकते हैं, हमने इसे "file-tools" ग्रुप में सफलतापूर्वक जोड़ा है:

Trix और Turbo Frames का उपयोग करके रेल्स में डायनामिक टेबल एडिटर बनाएं

अब आइए Turbo की मदद से टेबल जोड़ने और हेरफेर करने पर लौटते हैं। इसके लिए, हमें पहले create एक्शन के साथ एक कंट्रोलर की आवश्यकता होगी:

 

यह एक्शन कमोबेश उस 'On Rails' ब्लॉग पोस्ट से उधार लिया जा सकता है जिसे हमने परिचय में उद्धृत किया था। यह क्लाइंट साइड पर अटैचमेंट इन्सर्ट करने के लिए आवश्यक JSON का निर्माण करता है: जिसमें एक SGID और content शामिल है जो editor पार्शियल से रेंडर किया गया है, जैसा कि हम बाद में देखेंगे।

 

हम अपने कॉन्फ़िगरेशन में प्रासंगिक संसाधनपूर्ण टेबल रूट्स जोड़ते हैं:

 

अब गहरे अंत में डुबकी लगाने का क्षण आता है: हमें अपना टेबल मॉडल बनाना होगा। पहले, आइए ActionText::Attachable शामिल करें और प्रासंगिक पार्शियल पथ परिभाषित करें:

 

ध्यान दें कि हमने अभी तक परिभाषित नहीं किया है कि टेबल की सामग्री कैसे संग्रहीत की जाती है। क्योंकि हमने इसे अपने डेटाबेस में JSON(B) कॉलम के रूप में घोषित किया था, हम किसी भी प्रारूप को चुनने के लिए स्वतंत्र हैं। उद्धृत ब्लॉग पोस्ट से थोड़ा विचलन करते हुए, आइए दो-आयामी ऐरे के साथ जाएं। इस प्रकार, हम बस content पर नेस्टेड लूप कर सकते हैं जैसे:

 

उपरोक्त पार्शियल जब भी ActionView द्वारा अनुरोध किया जाता है, रेंडर होगा, उदाहरण के लिए। अगला, हमें Trix में इंलाइन उपयोग के लिए एक editor पार्शियल भी तैयार करना होगा:

 

एकमात्र अंतर, जैसा कि आपने शायद देखा है, यह है कि हमने अब इसे SGID को DOM आईडी के रूप में उपयोग करके Turbo Frame में लपेट दिया है। इसके अलावा, हम सेपरेटर ब्लॉक्स को रो और कॉलम इंडेक्स प्रदान करते हैं और इनर DIV को contenteditable बनाकर इंलाइन संपादन के लिए तैयार करते हैं — हम बाद में उस पर पहुंचेंगे।

अब हम अपने टूलबार के टेबल बटन को सर्वर-साइड कंट्रोलर एक्शन से जोड़ेंगे जिसे हमने अभी लिखा है। ऐसा करने के लिए, हमें पहले रेल्स की request.js लाइब्रेरी को प्रोजेक्ट में लाना होगा। यह लाइब्रेरी उचित CSRF-टोकन्स आदि सहित क्लाइंट से post रिक्वेस्ट्स को प्रशासित करने में हमारी मदद करेगी:

 

एक नया Trix टेबल Stimulus कंट्रोलर बनाएं

अब जब सब कुछ सेट हो गया है, आइए एक नया trix-table Stimulus कंट्रोलर बनाएं। इसमें, हम अपने टूलबार बटन द्वारा संदर्भित attachTable एक्शन को लागू करेंगे:

 

यह टेबल के create रूट पर POST करेगा, JSON प्रतिक्रिया को Trix अटैचमेंट के रूप में इन्सर्ट करेगा। यह फिर से OnRails ब्लॉग पोस्ट से उधार लेता है, डिप्रिकेटेड rails-ujs कॉल्स को नए request.js लाइब्रेरी के लिए एक्सचेंज करता है।

अब हमें वास्तव में इस कंट्रोलर को अपने ऐप में उपयोग करना होगा, इसे फॉर्म के मार्कअप में जोड़कर:

 

Stimulus.js की सुंदरता यह है कि form एलिमेंट में केवल दो डेटा एट्रिब्यूट्स जोड़ने से वांछित परिणाम प्राप्त होता है। अब हम अपने आर्टिकल के कंटेंट में एक बटन क्लिक से टेबल जोड़ने में सक्षम हैं:

Trix और Turbo Frames का उपयोग करके रेल्स में डायनामिक टेबल एडिटर बनाएं

Turbo Frames के माध्यम से टेबल में हेरफेर

अब जब हम टेबल अटैचमेंट्स बना सकते हैं, तो आइए अपना ध्यान सामग्री में हेरफेर करने पर केंद्रित करें। जैसा कि यह पता चला है, Turbo Frames यहां लगभग एक प्राकृतिक फिट हैं।

टेबल रो और कॉलम जोड़ें और हटाएं

टेबल रो और कॉलम जोड़ने और हटाने के लिए, हम चार बटनों से मिलकर एक मिनी-टूलबार बनाते हैं, प्रत्येक ऑपरेशन के लिए एक। button_to हेल्पर का उपयोग करें और URL को संबंधित टेबल के लिए update रूट पर सेट करें। आइए उस ऑपरेशन को अतिरिक्त पैरामीटर्स के रूप में जोड़ें जिसे हम ट्रिगर करना चाहते हैं:

 

बदले में, हमें अपने TablesController में संबंधित कंट्रोलर एक्शन(एस) भी जोड़ने होंगे। ध्यान दें कि update एक्शन उन एक्शन्स को मॉडल को डेलीगेट करता है।

 

टेबल की संरचना में परिवर्तन सेव होने के बाद, हम टेबल के एडिट व्यू पर रीडायरेक्ट करते हैं। यह वही editor पार्शियल रेंडर करता है, जिसका साइड-इफेक्ट एक ही Turbo Frame को संदर्भित करना है। इस प्रकार Turbo मिलान फ्रेम का पता लगा सकता है और एक को दूसरे के लिए प्रतिस्थापित कर सकता है।

 

अब हमें Table मॉडल पर लापता कमांड्स को लागू करना होगा।

 

उल्लेखनीय रूप से, हमारे दो-आयामी ऐरे की सरल डेटा संरचना के कारण, add/remove<sub>column</sub>/row मेथड्स केवल कॉलम और रो काउंट को संशोधित करने के लिए प्रॉक्सी हैं। एक बार जब यह जगह में हो जाता है, तो हम बटन क्लिक के साथ अपने टेबल की संरचना को बदल सकते हैं:

Trix और Turbo Frames का उपयोग करके रेल्स में डायनामिक टेबल एडिटर बनाएं

टेबल सेल्स की सामग्री संपादित करें

कॉलम और रो की संख्या बदलने के अलावा, हम सेल्स की सामग्री को भी संपादित करना चाहते हैं। इसे प्राप्त करने के लिए, हम फिर से उद्धृत ब्लॉग पोस्ट पर भरोसा करेंगे और एक Stimulus टेबल एडिटर कंट्रोलर बनाएंगे।

 

updateCell मेथड जब भी कोई सेल संपादित होता है, तो रो और कॉलम इंडेक्स को पैरामीटर्स के रूप में पास करते हुए एक PATCH रिक्वेस्ट जारी करेगा। अब, हमें बस इसे अपने DOM से जोड़ना है:

 

सर्वर-साइड TablesController, निश्चित रूप से, अब इस ऑपरेशन को संभालने का एक तरीका चाहिए। सौभाग्य से, यह हमारे सरलीकृत प्रूफ ऑफ कॉन्सेप्ट में एक और शाखा को हमारी शर्त में जोड़कर आसानी से किया जाता है। हम यह भी सुनिश्चित करते हैं कि update एक्शन अब JSON-टाइप रिक्वेस्ट्स को संभाल सकता है, भले ही यह यहां केवल एक खाली ऑब्जेक्ट वापस कर रहा हो।

 

ध्यान दें कि एक प्रोडक्शन ऐप में, मैं आपको ऑपरेशन को साफ करने के लिए if/elsif/else कंडीशन के अलावा एक अलग रणनीति चुनने की सलाह दूंगा। मैं शायद इस मामले में एक Mediator या Proxy तक पहुंचूंगा।

रूबी में Trix की सीमाएं

इस बिंदु तक, मैं मानता हूं कि यह विवरण पूरी तरह से समझ में आया है, लेकिन मैंने एक महत्वपूर्ण विवरण छोड़ दिया है। जबकि हम अंतर्निहित डेटाबेस मॉडल को ठीक से बनाए रख रहे हैं, हम इसे Trix के आंतरिक शैडो प्रतिनिधित्व के साथ सिंक नहीं कर रहे हैं। इसलिए जब हम इससे फोकस हटाते हैं तो टेबल पहले से स्टोर किए गए प्रतिनिधित्व पर वापस आ जाता है:

Trix और Turbo Frames का उपयोग करके रेल्स में डायनामिक टेबल एडिटर बनाएं

यदि हम अभी पेज को रीफ्रेश करते हैं, तो जोड़ी गई सामग्री दिखाई देगी, क्योंकि Trix का डॉक्यूमेंट नए सिरे से इनिशियलाइज़ होता है।

मैंने इस समस्या को उस स्थान पर पिन किया है जहां Trix अपने आंतरिक डॉक्यूमेंट को सिंक करता है जब चयन बदलता है। यह शैडो एलिमेंट से इसे बस अनफर्ल करता है।

मैंने turbo:submit इवेंट में हुक करने और टेबल को ब्लर करते समय सिंक को रोकने की कोशिश की, लेकिन मेरे द्वारा आए समाधान सभी बहुत बालों वाले और आंतरिक API पर अत्यधिक निर्भर लगते हैं।

इससे निपटने का सबसे Turbo-esque तरीका, मुझे लगता है, पूरे फॉर्म को एक उत्सुकता से लोड किए गए Turbo Frame में लपेटना होगा और इसे बताना होगा कि जब भी Trix की सामग्री बदलती है तो रीलोड करें।

कुछ ऐसा करना चाहिए:

 

यदि आप अपने फॉर्म को एक Turbo Frame में संलग्न करते हैं जिसे आप src से लोड करते हैं:

 

यह दृष्टिकोण केवल पहले से ही बने बेस रिकॉर्ड्स के साथ काम करता है, हालांकि।

Trix पर चेतावनी के अंतिम शब्द

हमारे द्वारा बनाया गया प्रूफ ऑफ कॉन्सेप्ट सर्वर-रेंडर्ड HTML का उपयोग करता है ताकि टेबल्स को JSON में सीरियलाइज़ करने और जावास्क्रिप्ट इवेंट्स के लिए सुनने की अतिरिक्त जटिलता से छुटकारा मिल सके। यह किसी भी ActionText इंस्टॉलेशन के लिए पोर्टेबल है और आसानी से एक जेम में निकाला जा सकता है।

कुछ कमियां हैं, हालांकि, सबसे स्पष्ट एक Trix के डॉक्यूमेंट मॉडल के साथ आवश्यक पुनः सिंकिंग है। ऐसी स्थितियां हो सकती हैं जहां प्रस्तावित वर्कअराउंड कार्यान्वयन योग्य हो और अन्य जहां यह नो-गो हो। जब तक Trix एक Turbo-संगत इंटरफेस प्राप्त नहीं करता, तब तक इसके आसपास कोई रास्ता नहीं है।

दूसरा कैच यह है कि यह Trix की undo कार्यक्षमता का उपयोग नहीं करता (लेकिन यह किसी भी Trix अटैचमेंट के लिए सच है)। इसी तरह, आंतरिक API को ट्वीक करने के बजाय अपस्ट्रीम परिवर्तनों की प्रतीक्षा करना बुद्धिमानी होगी।

समापन

इस पोस्ट में, हमने ActionText अटैचमेंट्स की मूल बातें पर एक त्वरित नज़र डालकर शुरू किया। फिर हमने ActionText मॉडल में एक टेबल जोड़ा और Turbo Frames का उपयोग करके इसे ट्वीक किया। अंत में, हमने Trix का उपयोग करने की कुछ सीमाओं को छुआ।

चूंकि Trix v2 चल रहा है, जिसमें CoffeeScript से सादे आधुनिक जावास्क्रिप्ट में अनुवाद की विशेषता है, अब इसकी Turbo संगतता को संबोधित करने का एक अच्छा समय होगा। वर्तमान में, ऐसे रैपर का दायरा कैसा दिख सकता है, यह मेरी क्षमताओं से परे है, लेकिन यह निश्चित रूप से अवसर की एक खिड़की की तरह दिखता है।

हैप्पी कोडिंग!

P.S. यदि आप रूबी मैजिक पोस्ट को प्रेस से बाहर आते ही पढ़ना चाहते हैं, तो हमारे रूबी मैजिक न्यूज़लेटर की सदस्यता लें और कभी भी एक भी पोस्ट मिस न करें!


  1. पायथन में दिए गए इंडेक्स के साथ स्ट्रिंग को शफल करने का प्रोग्राम पायथन में दिए गए इंडेक्स के साथ स्ट्रिंग को शफल करने का प्रोग्राम

    मान लीजिए हमारे पास एक स्ट्रिंग s और इंडेक्स की एक सूची ind है, वे समान लंबाई के हैं। स्ट्रिंग s को इस तरह शफल किया जाएगा कि स्थिति i पर मौजूद वर्ण, फाइनल स्ट्रिंग में indices[i] पर चला जाए। हमें फाइनल स्ट्रिंग ढूंढनी है। उदाहरण के लिए, यदि इनपुट s = ktoalak, ind = [0,5,1,6,2,4,3] है, तो आउटपुट kolk

  1. HTML DOM Style borderImageOutset प्रॉपर्टी HTML DOM Style borderImageOutset प्रॉपर्टी

    HTML DOM borderImageOutset प्रॉपर्टी का उपयोग उस मान को सेट या लौटाने के लिए किया जाता है जिससे बैकग्राउंड इमेज क्षेत्र एलिमेंट बॉर्डर बॉक्स से आगे बढ़ता है। top, left, right और bottom के लिए मानों का उपयोग करके हम निर्दिष्ट कर सकते हैं कि बैकग्राउंड इमेज एलिमेंट के संबंधित बॉर्डर से कितना आगे बढ़े

  1. Ruby डेवलपर्स के लिए आवश्यक डेटा स्ट्रक्चर्स: एक व्यावहारिक गाइड Ruby डेवलपर्स के लिए आवश्यक डेटा स्ट्रक्चर्स: एक व्यावहारिक गाइड

    Arrays को समझना जब आप प्रोग्रामिंग के बारे में पढ़ना शुरू करते हैं तो एरे पहला डेटा स्ट्रक्चर है जिसके बारे में आप सीखते हैं। एरे मेमोरी के एक सन्निहित हिस्से का उपयोग करते हैं जहां ऑब्जेक्ट्स एक के बाद एक बिना अंतराल के संग्रहीत होते हैं। C जैसी निचले स्तर की प्रोग्रामिंग भाषाओं के विपरीत, Ruby आपक