שדרוג לריילס5: מה נשבר ואיך מתקנים

09/01/2017

השדרוג לריילס5 עבר יחסית חלק, ואם אתם קוראים את זה דרך האתר מוזמנים לראות שהכל די עובד. שלושה דברים כן נשברו בתהליך אז הנה הסיפורים והתיקונים, בתקווה שיעזור גם לכם.

1. שינוי בפונקציה ids

ההפתעה הראשונה והגדולה ביותר היתה קוד שתמיד עבד ופתאום הפסיק בשליפה של ids של רשומות. דמיינו מודל של קבוצה ומודל של משתמש, ומשתמש שייך לקבוצה באמצעות היחס:

class Group < ActiveRecord::Base
  has_many :group_users
  has_many :users, through: :group_users
end

בריילס4 בהנתן קבוצה יכולתי להשתמש בקוד הבא כדי לקבל ids של כל המשתמשים בה:

group.user_ids

בריילס5 זה עדיין עובד אבל מחזיר מערך ריק. רק אחרי ששולפים את רשומות כל המשתמשים באופן יזום המערך מתחיל לתפקד ולכן נקבל:

# returns empty array
group.user_ids

group.users

# now returns the real array of user ids
group.user_ids

לא הצלחתי למצוא התיחסות לזה בתיעוד או להבין למה זה קורה, אבל מרגע שאתם מודעים לבעיה קל לעקוף אותה ולהחליף בקוד את כל המופעים של user_ids (או כל מערך ids אחר) ל users.ids שכן עובד.

אם יש לכם רעיון למה זה קורה או קישור להסבר שימו בתגובות ותזכו למצוות.

2. אקטיב אדמין מהגיהנום

יש בעיה עם ספריות שהן באמת מאוד טובות אבל מנוהלות גרוע, ו active admin היא בדיוק אחת כזאת. מצד אחד היא חוסכת לי המון עבודה, קל להתאים אותה ובוודאות בלעדיה מסכי הניהול היו נראים הרבה פחות טוב. מצד שני הגירסא החדשה ביותר ששוחררה היא 1.0.0pre4, אבל בגיטהאב הקוד חדש יותר. בפרט הקובץ app/assets/javascripts/active_admin/jquery_ui.js.erb נראה כך בגירסת ה master:


<% jquery_ui_path = if Jquery::Ui::Rails::VERSION >= "5"
                      "jquery-ui/"
                    else
                      "jquery.ui."
                    end
%>
<% jquery_ui_widgets_path =
                    if Jquery::Ui::Rails::VERSION >= "6"
                      jquery_ui_path + "widgets/"
                    else
                      jquery_ui_path
                    end
%>
<% require_asset "#{jquery_ui_widgets_path}datepicker" %>
<% require_asset "#{jquery_ui_widgets_path}dialog" %>
<% require_asset "#{jquery_ui_widgets_path}sortable" %>
<% require_asset "#{jquery_ui_widgets_path}tabs" %>
<% require_asset "#{jquery_ui_path}widget" %>

וכך בגירסא 1.0.0pre4:

<% jquery_ui_path = if Jquery::Ui::Rails::VERSION >= "5"
                      "jquery-ui/"
                    else
                      "jquery.ui."
                    end
%>
<% require_asset "#{jquery_ui_path}datepicker" %>
<% require_asset "#{jquery_ui_path}dialog" %>
<% require_asset "#{jquery_ui_path}sortable" %>
<% require_asset "#{jquery_ui_path}widget" %>

חדי העין יכולים להבחין בבלוק שלם שחסר בגירסא הישנה יותר, בלעדיו ריילס לא יצליח למצוא את jquery-ui-rails בגרסאות חדשות של האחרון. לי יש הרגל לקבע גרסאות ב Gemfile כדי לא לשבור דברים במעבר בין מכונות ולקח לי יותר מדי זמן למצוא שהאתר לא נדלק בגלל אותו בלוק חסר. בקיצור השורה האמיתית ב Gemfile צריכה להיות:

gem 'inherited_resources', github: 'activeadmin/inherited_resources'
gem 'activeadmin', github: 'activeadmin'

כרגע זה הג'ם היחיד שאני משתמש בו ללא מספר גירסא.

3. ביטול טעינה אוטומטית של ספריית lib

ספריית lib ירדה מרשימת הספריות שנטענות אוטומטית, ולכן אם בניתם על הקבצים בה יש צורך להוסיף require באופן ידני בכל קובץ שטוען דברים מ lib באופן הבא:

require './lib/someclass'

אפשרות שניה היא פשוט להעביר את כל תוכן lib לתוך תיקיית app (זה מה שאני עשיתי) ואפשרות שלישית היא להוסיף לקונפיגורציה את השורה:

# config/application.rb
config.eager_load_paths << Rails.root.join('lib')

אני חושב שהאפשרות שבחרתי היא הגרועה ביותר, ובטח אחליף לראשונה או לשלישית בהמשך. אשמח לשמוע גם מה דעתכם בתגובות.