تجاوز user_guardian.rb في إضافة (لا حاجة لعمل fork!)

مرحبًا، عذرًا على السؤال المبتدئ. لقد قرأت الوثائق ولكنني أحتاج إلى بعض التوجيه، من فضلك.

لقد قمت بتفرع مشروع Discourse وقمت بإجراء تعديلات خاصة بي، وأود الآن نشر نسختي الخاصة. يشرح دليل المساهمة كيفية إجراء التغييرات وتقديم طلب سحب (PR)، لكن في هذه الحالة، لا أريد تقديم طلب سحب. أود فقط أخذ تغييراتي البسيطة وتشغيل تثبيت Discourse بناءً عليها. لقد ظننت أن الطريقة الصحيحة هي تغيير هذا السطر ليشير إلى مستودعي الخاص:

لقد قمت بذلك وقمت بالتثبيت، لكن التغييرات التي أجريتها لم تظهر، لذا من الواضح أنني أفعل شيئًا خاطئًا. هل لديكم أي أفكار؟ شكرًا لكم!

تعديل:
لأغراض الشفافية، وفي حال كان هناك طريقة أسهل للقيام بذلك، كل ما أحاول فعله هو السماح للمستخدمين المجهولين بتغيير أسماء المستخدمين الخاصة بهم عند الدخول في الوضع المجهول. الأمر بسيط مثل تغيير false إلى true في هذا السطر:

إذا كانت هناك طريقة أفضل، فأنا مستعد للاستماع. لكن هذا كل ما أحتاجه لتمكينه. أنا ماهر في Python وJava والعديد من الأشياء الخلفية الأخرى، لكنني لا أعرف شيئًا عن Ruby/JavaScript/HTML إلخ.

تعديل 2:
وفقًا لـ منشور رأيته في مكان آخر، قمت بتحديث ملف app.yml على النحو التالي:

run:
- exec:
 cd: /var/www/discourse
 cmd:
    - sudo -u discourse git remote set-url origin https://github.com/my/forked/discourse.git
    - sudo -u discourse git fetch origin
    - sudo -u discourse git checkout origin/master

لا يزال لا يعمل بعد إعادة بناء التطبيق. يبدأ بشكل صحيح ولكن يبدو أن تغييراتي غير موجودة.

أليس من الممكن تغليف التغييرات الخاصة بك في إضافة واستخدامها بدلاً من ذلك؟

5 إعجابات

كل من فعل ذلك ندم بشدة. ولا يمكنك الحصول على الكثير من المساعدة هنا.

مهما كنت تفعل، افعله في إضافة (plugin).

10 إعجابات

حسنًا، هل لديك أي فكرة عن كيفية القيام بذلك عبر إضافة؟

مرحبًا @leighno5

من خبرتي الشخصية، أعتقد أن كتابة إضافات (plugins) بلغة Ruby لتنفيذ ما تفعله في “النسخة المشتقة” (fork) الخاصة بك يكون أسهل بكثير عند استخدام إضافة، وذلك عندما نفهم Ruby و Rails بدرجة كافية لكتابة إضافة لـ Discourse بسهولة (أو تعديل أي فئة في Rails).

إذا لم نفهم Rails و Ruby بدرجة كافية لكتابة إضافة لـ Discourse، فإن تجربتي تقول إن نسخ Discourse وتعديل النواة (core) يعتبر “خاطئًا”.

أعتقد أن التشبيه المناسب هو التالي (آسف على هذه الفكرة البسيطة):

“شخص يجد صعوبة في المشي، فيقرر الجري بدلاً من ذلك.”

دعني أشرح، إذا لم تمانع:

قبل أن أبدأ في كتابة تطبيقات Rails (لا علاقة لها بـ Discourse)، وحاولت كتابة إضافات لـ Discourse، كنت أشعر بالضياع قليلاً؛ بل وحتى كنت منزعجًا من Discourse إلى حد ما، أعتقد. الأمر يشبه عندما تريد ضرب كرة الغولف لأول مرة؛ لا تسير في خط مستقيم وتتطلب الكثير من الجهد لضرب الكرة في منتصف الملعب. نسخ Discource يشبه استخدام عصا القيادة الكبيرة (driver) في منطقة التدريب قبل أن تتقن الضربات القصيرة (chip) والـ putts باستخدام العصا القصيرة!

أخذت استراحة من تعديل Discourse (منذ عدة أشهر) وعملت لفترة في بناء عدد من تطبيقات Rails من الصفر؛ ثم (وفقط بعد ذلك) بدأت أطور بعض “المعرفة الحدسية” حول Rails. بعد ذلك، عندما قررت تعديل Discourse (أقوم حاليًا بتشغيل 6 إضافات مخصصة كتبتها لـ Discourse في بيئة الإنتاج)، أصبحت كل شيء بديهيًا، وأصبحت الإضافات التي تعدل النواة الأساسية لـ Ruby بسيطة للغاية.

Ruby مرنة للغاية. يمكننا تجاوز أي فئة، أي كائن. يمكننا إعادة تعريف كل جانب من جوانب Ruby. مع بعض الخبرة، نبدأ في القول “واو”، لم أكن أعرف أن Ruby بهذه المرونة (والقوة)، ونبدأ في “أن نصبح خطرين” لأننا يمكننا الطيران مثل سوبرمان باستخدام Ruby و Rails. نحن في بداية رحلتنا مع Ruby و Rails في ذلك الوقت، وليس في نهايتها!

مع معرفة Ruby و Rails التي اكتسبتها في عام 2020، ومع ما أعرفه الآن، لن أنسخ Discourse أبدًا وأجري تغييرات على نواة Ruby و Rails كما تقترح، لأن الإضافات سهلة جدًا لتجاوز وتعديل فئات Ruby، عندما نفهم أساسيات فئات Ruby وأساسيات البرمجة الوصفية (meta-programming).

أعتقد أن ما أقوله، آسف على الصراحة، هو أنه إذا اعتقد شخص ما أنه يحتاج إلى تعديل نواة Discourse لإجراء بعض التغييرات البسيطة على Ruby؛ فهذا يعني أنه لا يفهم Ruby و Rails بدرجة كافية؛ لأنه لو فهمهما، لما عدّل النواة وكتب ببساطة إضافة سريعة لتجاوز الفئات واستمتع بـ “الرقص مع القردة” (monkey-patching).

من ناحية أخرى، إذا أردت فعل شيء مجنون وأشعر بالتعاسة مثل استبدال EmberJS في Discourse بـ React و Ant Design، فإن النسخ (fork) سيكون الخيار الوحيد! ومع ذلك، في رأيي، لا يُعرّف “Discourse” بـ “مكتبات الجافاسكريبت”. يُعرّف Discourse بمهارات فريق التطوير الأساسي (الأشخاص) واهتمامهم بالتفاصيل، وخدمة العملاء، ونهج الفريق في تطوير الكود مفتوح المصدر، وخط أنابيب ميزات SPA الخاص بهم، وكل عملهم الشاق! سيكون الأمر جنونيًا قليلاً (في رأيي) إهدار كل هذا العقل فقط لأننا قد نفضل Ant Design (مع React) أو VueJS على Ember.

ينطبق نفس الشيء تمامًا بل وأكثر إذا كنا سنعدل نواة Discourse هنا وهناك! سيكون الأمر “مجنونًا” قليلاً نسخها لفعل ذلك، وإهدار “الأشخاص” الذين يمثلون “الحقيقي” من Discourse (وليس الكود).

أتحدث فقط من رحلتي الشخصية في عام 2020 لتعلم Ruby و Rails. الآن، أصبح الأمر أسهل (الأساسيات) وأنا “خطير”، LOL. يمكنني “الرقص مع القردة مع أي شيء”، وهو ليس دائمًا أمرًا جيدًا؛ وهذا هو دور إضافات Discourse.

حافظ على النواة صلبة كصخرة، واستمتع بـ “الرقص مع القردة” في Discourse باستخدام الإضافات.

أتمنى أن يكون هذا مفيدًا.

ملاحظة: بينما كنت أكتب هذه الإجابة، كتبت أنت:

هذا يثبت نقطي نوعًا ما، أليس كذلك؟

كتابة “إضافة” في Discourse هي كتابة “كود Ruby” (على مستوى واحد)، وبالنسبة للآخرين فإن الأمر أعمق بكثير (في EmberJS).

قبل أن تبدأ في كتابة إضافات لـ Discourse، نصيحتي الودية، التي قد تبدو غير ذات قيمة بالنسبة لك، هي أن تبدأ أولاً في تطوير بعض تطبيقات Ruby on Rails. تعلم طريقك في Ruby و Rails، على الأقل الأساسيات، وبعد ذلك، ستكون قد أجبت على سؤالك أعلاه بنفسك.

أنا كنت في مكالمة هاتفية هذا الصباح مع عميل لمدة ثلاث ساعات نتحدث عن تطبيق Rails، والتحقق من صحة البيانات (validations)، والنماذج (models)، وما إلى ذلك، ثم أخذت استراحة بعد كتابة بعض إجراءات العمل من المكالمة، وقرأت مشاركتك.

أقصر طريق لكتابة إضافات لـ Discourse، في رأيي، هو تعلم Rails أولاً.

أتمنى أن يكون هذا مفيدًا!

5 إعجابات

إليك نقطة بداية جيدة:

3 إعجابات

لا، أنت محق تمامًا. ليس لدي أي خبرة مع Ruby على الإطلاق، لذا فلا إهانة هنا! لقد اطلعت على دليل الإضافات ومررت عليه عدة مرات، لكن لسوء الحظ، يستمر جهلي بـ Ruby في إحباطي، ولا أدري كيف سأكتب إضافة تتجاوز ذلك الجزء الصغير من الكود في ملف user-guardian للسماح للمستخدمين المجهولين بتغيير أسمائهم. :confused:

إعجابَين (2)

مرحبًا @leighno5

نعم، أفهم ذلك تمامًا.

تم كتابة مواضيع “كيف أفعل” هذه من قبل مطورين موهوبين للغاية يتمتعون بأكثر من عقد من الخبرة في برمجة Rails و Ruby (وربما أكثر من ذلك). في الواقع، بعض هؤلاء المطورين من بين أفضل مطوري Ruby و JavaScript في العالم.

أنا متأكد بنسبة 100% من أن هؤلاء المطورين تعلموا Rails و Ruby قبل أن يكتبوا أول إضافة لـ Discourse.

في الواقع، تعلم Rails ليس صعبًا جدًا؛ لكنك تحتاج إلى ممارسة “الطقس العملي” لبناء بعض تطبيقات Rails من الصفر. ليس مجرد متابعة دروس على YouTube (وهو أمر جيد)، بل بناء تطبيق يعمل فعليًا حيث يتعين عليك التعامل مع إعداد قاعدة البيانات، وتوليد نماذجك الخاصة، وتوليد وحدات التحكم الخاصة بك، وكتابة تحقق من صحة النماذج، وكتابة وحدات التهيئة، ووحدات المساعدة، وإجراء هجرات (تعديلات) على قاعدة البيانات، والعمل مع Ruby المدمج والمزيد.

في الواقع، الأمر ممتع جدًا، وهو “أقصر طريق” لتعلم الشعور بالراحة في كتابة إضافة (فيما يتعلق بجزء Rails، لا أعمل مع Ember شخصيًا، لكنني أحب جانب Rails)!

أيضًا، يجب أن تتعلم وحدة تحكم Rails! وحدة تحكم Rails ممتعة حقًا، وأنا أستخدمها يوميًا بمتعة!

اليوم، كنت أقوم بعمل AnyDesk مع عميلي المفضل، وقال: “هل يمكننا الحصول على هذا العرض الجديد للمخزون؟”. أراد أن يشاهدني أقوم بكل ذلك. بعد أن أقمناه وجعلناه يعمل، قال في نهاية المكالمة: “لقد قمت بشيء في Rails خلال 30 دقيقة كان سيستغرق أسابيع عديدة قبل عقود!!”. رائع حقًا، @leighno5. ابدأ فورًا!!

بعد أن تتعلم Rails، ستقول: “واو”، إن كتابة إضافات Discourse سهلة نسبيًا، على الأقل فيما يتعلق بجزء Rails و Ruby!!

آمل أن يكون هذا مفيدًا.

3 إعجابات

انظر إلى كود #plugin الموجود. هناك عدد هائل منها الآن، لذا توجد أمثلة كثيرة. لا تتجاهل قراءة الأعمال السابقة حتى تتمكن من الاستفادة منها.

يبدو أنك تريد ببساطة تجاوز طريقة واحدة، وهو ما يتم عن طريق إعادة تعريفها في ملف plugin.rb (على الرغم من أن أفضل الممارسات هي فصلها إلى ملف خاص بها لكل وحدة، لكن هذا لا يستحق الجهد لطريقة واحدة!)

5 إعجابات

مع مخاطر إظهار جهلي أكثر واستغلال اللطف الذي أظهرتموه لي بالفعل، هل تودون التوسع قليلاً في هذا؟ أو إذا كنتم تدركون مثالاً آخر حيث قام شخص ما بتجاوز وحدة نمطية ويمكنكم ربط ذلك، سأكون ممتناً. لست معارضاً على الإطلاق لـ “اقرأ دليل المستخدم”، لكن عدم فهمي لكيفية عمل Discourse محبط، على الرغم من كل الوقت الذي قضيته في مراجعة الدروس والوثائق المختلفة. ونعم، أعرف أن مثل هذه الأسئلة البسيطة قد توحي بأنني بذلت جهداً قليلاً في ذلك، لكنني أؤكد لكم أن هذا ليس هو الحال!

3 إعجابات

إليك مثال حيث قمنا بتعريف دالة في PostGuardian:

يمكنك فعل شيء مماثل في UserGuardian باستخدام اسم الدالة الحالي، مما سيؤدي إلى تجاوزها.

الحل البسيط (لجعلها تعمل، حتى لو لم يكن ذلك متينًا):

اكتب ببساطة كود الدالة الأصلي وقم بإجراء التعديل المطلوب. العيب: إذا قام Discourse بتغيير الكود، فقد يتعطل مثيل البرنامج المساعد الخاص بك.

الحل المتقدم (حل أكثر متانة):

لإضافة قيمة إضافية، قد تتمكن من استخدام super لوراثة الدالة الأصلية، لكن لا يضمن ذلك العمل لأسباب لن أشرحها هنا، مع أن ذلك يعتبر أفضل ممارسة لأنه سيضمن أخذ أي تحديثات تُجرى على تلك الدالة في Discourse في الحسبان دون الحاجة إلى تعديل البرنامج المساعد الخاص بك.

Discourse منصة، ويحتاج الأمر وقتًا لتعلمها. فقط تقدّم خطوة بخطوة.

6 إعجابات

هذا ما كنت أقلق منه. هل الطريقة المتقدمة المذكورة في الفقرة التالية مغطاة في دليل كيفية الاستخدام؟ هل هناك مثال جيد وبسيط لاستخدامها في إضافة موجودة يمكن استخدامه (نسخه) عند إنشاء إضافة جديدة؟

لا تقلق بشأن الطريقة المتقدمة في الوقت الحالي. فقط اجعلها تعمل. يمكنك البحث عن Ruby on Rails بشكل عام في أدلة الإنترنت الأخرى. هذا الأمر خارج نطاق Discourse تحديدًا وهذا المنتدى. فقط كن على علم بذلك.

إعجاب واحد (1)

حسناً، شكراً لك! لنفترض أنني قمت بكتابة إضافة قصيرة. إذا كنت قد فهمت الأمر بشكل صحيح، فيجب أن أفحص الكود الأساسي في كل ترقية وأعيد كتابة الإضافة إذا تغير الكود الأساسي ذي الصلة. هل هذا كل شيء؟ شكراً لك.

إعجاب واحد (1)

هذا صحيح. فقط تفقده من حين لآخر، وخاصة إذا بدأ في التعطل. كود الحارس (Guardian) أكثر أهمية لأنه يتعلق بترخيص موقع الترميز، لذا راقبه عن كثب.

الحل الآخر هو إضافة حالات اختبار (تُعرف أيضًا باسم المواصفات) وإعداد مهمة آلية لتشغيلها… لكن هذا يتطلب جهدًا أكبر!

إعجابَين (2)

مهمة إضافية أخرى هي إعداد travis-ci.org لتشغيل اختبارات الإضافة الخاصة بك، بحيث تحصل على تنبيه في حال حدوث أي خلل.

5 إعجابات

من الواضح أن هذه ليست مهمة يمكن الاستخفاف بها. أود تعديل نوافذ تسجيل الدخول/إنشاء حساب جديد، والتخلص من صورة تويتر. ربما يكون هذا الأخير مشروعًا أفضل للبدء به. شكرًا لك.

إذا صادف أحدكم هذا الموضوع وكان يشعر بالضياع مثلي تمامًا، فأنا أقدم لك أدناه الكود الخاص بي بعد أن نجحت في تشغيله كما هو مخطط له. لم أقوم بتعديل أي ملفات. بل قمت ببساطة بإنشاء ملف جديد باسم plugin.rb ووضعت فيه ما يلي:

# name: noms
# about: يسمح للمستخدمين في الوضع المجهول بتغيير أسماء مستخدمينهم
# version: 0.1


require_dependency 'guardian'
require_dependency 'guardian/user_guardian'

class ::Guardian
end

module ::UserGuardian
  def can_edit_username?(user)
    return false if SiteSetting.sso_overrides_username?
    return true if is_staff?
    return false if SiteSetting.username_change_period <= 0
    return true if is_anonymous?
    is_me?(user) && ((user.post_count + user.topic_count) == 0 || user.created_at > SiteSetting.username_change_period.days.ago)
  end


  def can_edit_name?(user)
    return false unless SiteSetting.enable_names?
    return false if SiteSetting.sso_overrides_name?
    return true if is_staff?
    return true if is_anonymous?
    can_edit?(user)
  end
end

هذا الكود يقوم بتجاوز فئة user_guardian.rb في نواة Discourse للسماح للمستخدمين بتغيير اسم مستخدمهم واسم حساباتهم المجهولة.

إذا قمت بمقارنة ما لدي هنا بما هو موجود في ملف user_guardian.rb في نواة Discourse، ستلاحظ وجود مجموعة من العناصر الأخرى التي لم أكن بحاجة للتعامل معها، لذا تركتها كما هي. كل ما احتجت إليه هو تعديل طريقتين فقط: can_edit_username و can_edit_name عن طريق تغيير بعض قيم الإرجاع من false إلى true، وقد تمكنت من تحقيق ما أريده.

بالتأكيد هناك تحسينات يمكن إجراؤها، ومن المرجح أن هناك ممارسات مثلى تمكنت من استنتاجها من خلال قراءة المنشورات المرتبطة هنا وفي أماكن أخرى، ولكن إذا كنت جديدًا تمامًا على لغة Ruby مثلي وتريد فقط تعديل شيء بسيط جدًا في النواة، فهذا مثال عملي مبسط لما تحتاج إلى فعله.

شكرًا جزيلًا للأشخاص في هذا الموضوع على صبرهم وتشجيعهم ومساعدتهم! وعلى وجه الخصوص إلى @merefield الذي ساعدني بالفعل في منشور آخر في الماضي.

10 إعجابات

ها ها ها

لقد قطعت شوطًا طويلًا منذ فكرتك الأولية في إنشاء نسخة منسوخة من Discourse والتخلي عن الفرع الرئيسي لمثل هذه المهام البسيطة.

أحسنت :slight_smile:

4 إعجابات

هل اتبعت المسار الكامل Install Discourse on Ubuntu or Debian for Development أم أنك عملت فقط على موقعك الإنتاجي وسمحت للأمر أن يسير على ما يرام؟