uk
Feedback
ToCode

ToCode

Відкрити в Telegram

טיפים קצרים למתכנתים מאת ינון פרק

Показати більше
1 419
Підписники
Немає даних24 години
Немає даних7 днів
Немає даних30 день
Архів дописів
ToCode
1 419
 => false
הדרך להתמודד עם מספר מקורות עדכון בריילס היא לייצר מספר Validation Contexts. כל Validation Context מייצג את הטופס או המסך בו אנחנו רוצים לעדכן את ההודעה בצורה מסוימת, והוולידציות שבו יתאימו לאפשרויות באותו המסך. בחזרה להודעה אפשר לעדכן את הקוד בצורה הבאה:
class Message < ApplicationRecord
  validates :from, presence: true, on: :message_form
  validates :to, presence: true, on: :message_form
  validates :title, length: { minimum: 5 }, on: :message_form
  validates :body, presence: true, on: :message_form
end
בעת שמירת הודעה אנחנו נעביר עכשיו את הקונטקסט המתאים כדי שריילס ידע איזה וולידציות להפעיל:
m = Message.first
m.important = true
m.save(context: :message_index)
 => true
כרגע פונקציית update של ריילס לא יודעת לעבוד עם Custom Validation Context ולכן כדי לעבוד איתם בדרך כלל נרצה להוסיף פונקציה משלנו לכל ה Active Records ביישום:
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  def update_attibutes_with_context(attributes, *contexts)
    with_transaction_returning_status do
      assign_attributes(attributes)
      save(context: contexts)
    end
  end
end
ולסיום ב Controller נצטרך להוסיף את ה Context המתאים בכל פעולה:
class MessagesController < ApplicationController
  before_action :set_message, only: [:show, :edit, :update, :destroy, :toggle_important]

  # GET /messages
  # GET /messages.json
  def index
    @messages = Message.all
  end

  # GET /messages/1
  # GET /messages/1.json
  def show
  end

  # GET /messages/new
  def new
    @message = Message.new
  end

  # GET /messages/1/edit
  def edit
  end

  def toggle_important
    @message.important = !@message.important
    @message.save(context: :messages_index)
  end

  # POST /messages
  # POST /messages.json
  def create
    @message = Message.new(message_params)

    respond_to do |format|
      if @message.save(context: :message_form)
        format.html { redirect_to @message, notice: 'Message was successfully created.' }
        format.json { render :show, status: :created, location: @message }
      else
        format.html { render :new }
        format.json { render json: @message.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /messages/1
  # PATCH/PUT /messages/1.json
  def update
    respond_to do |format|
      if @message.update_attributes_with_context(message_params, :message_form)
        format.html { redirect_to @message, notice: 'Message was successfully updated.' }
        format.json { render :show, status: :ok, location: @message }
      else
        format.html { render :edit }
        format.json { render json: @message.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /messages/1
  # DELETE /messages/1.json
  def destroy
    @message.destroy
    respond_to do |format|
      format.html { redirect_to messages_url, notice: 'Message was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_message
      @message = Message.find(params[:id])
    end

    # Only allow a list of trusted parameters through.
    def message_params
      params.require(:message).permit(:from, :to, :title, :body)
    end
end
## אפשר ליצור וולידציה כללית (למרות שזה מבלבל את המשתמשים) ריילס מאפשר לנו ליצור וולידציה "כללית" על אוביקט שהתוצאה שלה תוצג ברשימת הודעות השגיאה של הטופס אבל לא עבור שדה מסוים. כמעט תמיד כשאתם באים לכתוב וולידציה כללית כזו שווה להשקיע עוד כמה דקות של מחשבה ולמצוא דרך טובה יותר לביצוע המשימה.

ToCode
1 419
ריילס הוא אומנם מהיר אבל גם שליחת הודעה לשרת המהיר בעולם תיקח יותר זמן מוולידציה שרצה אצל הלקוח בלי לדבר עם השרת. כמעט תמיד בכל מקום שיש וולידציה ב Active Record כדאי להוסיף גם וולידציה מקבילה בטופס (אני אומר כמעט כי זה לא תמיד אפשרי - לדוגמה וידוא שערך מסוים הוא ייחודי במערכת זה משהו שאפשר לעשות רק בצד שרת). בדוגמה שלנו אני יכול לעדכן את הטופס עם הקוד הבא וכך להרוויח גם וולידציה לפני שליחת ההודעה לשרת (כדי לקבל חווית משתמש טובה יותר), וגם וולידציה בצד השרת (בשביל אבטחת מידע ובשביל פרטים שהלקוח לא יודע עדיין):
<%= form_with(model: message, local: true) do |form| %>
  <% if message.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(message.errors.count, "error") %> prohibited this message from being saved:</h2>

      <ul>
        <% message.errors.full_messages.each do |message| %>
          <li><%= message %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.label :from %>
    <%= form.text_field :from, required: true %>
  </div>

  <div class="field">
    <%= form.label :to %>
    <%= form.text_field :to, required: true %>
  </div>

  <div class="field">
    <%= form.label :title %>
    <%= form.text_field :title, required: true, minlength: 6 %>
  </div>

  <div class="field">
    <%= form.label :body %>
    <%= form.text_area :body, required: true %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

ספריה בשם client_side_validations מתרגמת בצורה אוטומטית את ה Active Record Validations לוולידציות בצד לקוח באמצעות JavaScript ולפעמים כדאי להשתמש בה. ## וולידציה אינה אינדקס רעיון שני שחשוב לזכור הוא שהמטרה של וולידציה היא להציג הודעת שגיאה יפה למשתמש כשאותו משתמש מנסה להקליד נתונים לא נכונים בטופס. וולידציה ב Active Record לא תמנע מהמערכת שלכם לשמור מידע שגוי או שלא עובר וולידציה ויש המון דרכים לשמור מידע ולדלג על הוולידציה. אם חשוב לכם שמידע "לא נכון" לא ייכנס לבסיס הנתונים הדרך היחידה להבטיח את זה היא ליצור אינדקס או Constraint בבסיס הנתונים עצמו. נשים לב שבסיסי נתונים לא יודעים לעשות כל מה שהשרת שלנו יודע לעשות, וברובם אין דרך קלה להגדיר לדוגמה אורך מינימלי למחרוזת בעמודה. זה אומר שבהחלט יהיו מצבים בהם תהיה לכם וולידציה אבל חלק מהמידע בבסיס הנתונים לא יעבור אותה. במצב כזה משתמש יצטרך לעדכן ערכים בטופס גם אם הוא לא שינה אותם רק בשביל לשמור את המידע. בדוגמה שלנו, אני יכול ליצור מתוך Rails Console אוביקט הודעה תוך דילוג על הוולידציה:
m=Message.new(to: 'ynon')
m.save(validate: false)
באפליקציה עצמה אני אראה את ההודעה הזו ברשימת ההודעות ואוכל להיכנס לטופס עריכה כדי לעדכן אותה, אבל בתוך אותו טופס אני אהיה חייב לעדכן את השדות from, title ו body כדי שאוכל לשמור. ## היו זהירים כשאתם מוסיפים וולידציה חדשה למודל אין בעיה להוסיף וולידציה למודל שיש בו כבר נתונים (למשל מגירסה קודמת של האפליקציה) אבל עליכם להיות זהירים ואף פעם לא להניח שכל הוולידציות עוברות על נתונים קיימים. כל הוספה של וולידציה צריכה להתחיל ממחשבה על טופס ועל הודעה שמשתמש יראה כשהוא ממלא את הטופס. אם מוסיפים וולידציה על נתונים קיימים יש לוודא שמשתמש יכול לפתוח את האוביקט במצב עריכה ולהוסיף את הערכים החסרים כדי לעבור וולידציה (אחרת אי אפשר יהיה לשמור או לעדכן אפילו שדות אחרים). ## אפשר להגביל וולידציה ל Context מסוים המצב הזה של וולידציות חדשות הופך מבלבל במיוחד כשיש מספר דרכים לעדכן אוביקט במערכת. לדוגמה במערכת ההודעות שלנו אפשר לדמיין שלכל הודעה יהיה כפתור עם אייקון של כוכב במסך רשימת ההודעות שיסמן אותה בתור הודעה "חשובה". עכשיו יש לנו 2 דרכים לעדכן כל הודעה: 1. טופס העדכון הרגיל של הודעה 2. לחיצה על כפתור "כוכב" שמעדכנת רק את שדה "important" בהודעה, שדה חדש שיצרנו בשביל הפיצ'ר. אם באמת נלך לבנות את פיצ'ר הכוכבים נגלה שאנחנו לא יכולים לסמן בתור "חשוב" את ההודעה הלא וולידית שיצרנו בסעיף הקודם. ריילס ייכשל בטענה שהוא לא יכול לעדכן את האוביקט כי האוביקט נכשל בוולידציה, למרות שאנחנו עובדים מתוך ממשק אחר בו אי אפשר לשנות את השדות שלא עברו וולידציה. אפשר לראות את זה אם נריץ את הקוד הבא מתוך הקונסול:
m = Message.first
m.important = true
m.save

ToCode
1 419
# טיפים לשימוש טוב יותר ב Active Record Validations אחד הרעיונות היפים בריילס, ואחד הרעיונות שלקח לי הכי הרבה זמן להבין, הוא ה Active Record Validations. הסיפור בקצרה הוא שלפעמים יש לנו באפליקציה טפסים שמטרתם ליצור או לעדכן מידע בבסיס הנתונים. המידע בבסיס הנתונים בריילס מיוצג על ידי קלאס שנקרא Active Record, ולכן כשצריך לעשות וולידציה על המידע בטפסים אותם Active Records יהיו המקום האידאלי. בפוסט זה אראה בקצרה איך להשתמש ב Active Record Validations ביישום ולאחר מכן אמשיך למספר טיפים לשימוש נכון בהם. ## איך זה עובד ב Rails כל טבלה בבסיס הנתונים מיוצגת על ידי מחלקה שיורשת מ Active Record, וכל אוביקט ממחלקה זו מייצג שורה בטבלה. בהגדרת המחלקה אנחנו לא צריכים להגדיר את העמודות (ריילס מזהה אותן אוטומטית). הקוד הבא עשוי להיות קוד שמגדיר את החיבור בין אפליקציית Rails לטבלת ההודעות:
class Message < ApplicationRecord
end
בואו נניח שכל הודעה כוללת את השדות הבאים: 1. שם השולח 2. שם הנמען 3. נושא ההודעה 4. גוף ההודעה 5. תאריך יצירת ההודעה 6. תאריך עדכון אחרון של ההודעה קוד ריילס שיוצר את טבלת ההודעות נראה כך:
  create_table "messages", force: :cascade do |t|
    t.string "from"
    t.string "to"
    t.string "title"
    t.text "body"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end
כמו שהקוד כתוב אין וולידציות כלל על השדות בהודעה. אם נבנה טופס ליצירת הודעה חדשה, משתמש יוכל להזין כל ערך בטופס וגם להשאיר שדות ריקים. ה Active Record Validation נועד לתת את התשתית שמחברת בין וולידציה של השדות לבין הטופס שמשתמש ממלא, וזה עובד כך: 1. משתמש מזין מידע בטופס והמידע מגיע לשרת 2. השרת יוצר אוביקט Message וממלא אותו במידע שהמשתמש הקליד בטופס 3. השרת מפעיל Validation על האוביקט שנוצר. אם היו שגיאות, התוצאה של הוולידציה היא הוספת שדות מידע לאוביקט בצד השרת עם הודעות השגיאה המתאימות לפי השדות של האוביקט. 4. השרת יוצר HTML או JSON מאוביקט ה Message שנוצר (זה עם השגיאות) והודעות השגיאה המתאימות מוצגות בטופס או בתוך אוביקט ה JSON. לריילס יש גם תשתית די טובה שמחברת בין טופס לבין השגיאות כך שבקוד ה ERB אנחנו צריכים בסך הכל לכתוב את השדות בטופס באופן הבא:
<%= form_with(model: message, local: true) do |form| %>
  <% if message.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(message.errors.count, "error") %> prohibited this message from being saved:</h2>

      <ul>
        <% message.errors.full_messages.each do |message| %>
          <li><%= message %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.label :from %>
    <%= form.text_field :from %>
  </div>

  <div class="field">
    <%= form.label :to %>
    <%= form.text_field :to %>
  </div>

  <div class="field">
    <%= form.label :title %>
    <%= form.text_field :title %>
  </div>

  <div class="field">
    <%= form.label :body %>
    <%= form.text_area :body %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>
ובאופן אוטומטי החלק העליון יתמלא בהודעות השגיאה המתאימות שנלקחו ישירות מתוך ה Validation. בשביל הדוגמה אני מוסיף בקוד של message.rb את התוכן הבא:
class Message < ApplicationRecord
  validates :from, presence: true
  validates :to, presence: true
  validates :title, length: { minimum: 5 }
  validates :body, presence: true
end
המשמעות של הוולידציה היא שבעת הגשת הטופס תתווסף Server Side Validation על המידע וההודעה תישמר רק אם כל השדות עומדים בתנאים שהגדרתי, כלומר: 1. קיים ערך לשדה from 2. קיים ערך לשדה to 3. קיים ערך לשדה title באורך מינימלי של 5 תווים 4. קיים ערך לשדה body כל אחד מהשדות שלא מתאים לוולידציה יגרום להצגת הודעת שגיאה בראש הטופס ובנוסף ליצירת div חדש בתוך ה div עם הקלאס field שלו הקלאס field_with_errors, מה שיאפשר לצבוע את המקום הרלוונטי בטופס באדום. ועכשיו שאנחנו מבינים את הסיפור הזה הנה כמה דברים שחשוב לזכור לגבי וולידציות: ## הוולידציות נבדקות בצד שרת ואינן מחליפות Client Side Validations

ToCode
1 419
# כמה שווה לך Workflow אפקטיבי? פעם אחת לפני הרבה הרבה שנים (נו, שנתיים, אבל זה מרגיש הרבה) יצרתי כמה קיצורי דרך ספציפית לכתיבה בבלוג: התקנת Markdown Mode באימקס ולמדתי איך לכתוב איתו בעברית, חיברתי קיצור מקשים כך שהשמירה תהיה ישירה לשרת לתיקיה קבועה, על השרת כתבתי Cron Job שמושך קבצי Markdown מאותה תיקיה קבועה והופך אותם לפוסטים, ויש עוד כמה תהליכים ששולחים כל פוסט במייל לאנשים שרוצים לקבל או לערוץ טלגרם. כל עוד אני מקפיד להפעיל את האימקס פעם ביום ולכתוב, כל השאר קורה מעצמו. מצד השני, אם יום אחד אני לא כותב בזמן את הפוסט התהליכים משתגעים ובטעות איזה בוט מפרסם את הפוסט מאתמול פעם שניה. אם יום אחד אקח הפסקה של כמה שבועות בכתיבה אני אצטרך לכבות חלק מהתהליכים האוטומטיים. אחרי הכיבוי כשארצה לחזור לכתוב אצטרך למצוא מה כיביתי וללמוד מחדש איך עובדים עם הדברים. גם במערכות תוכנה שאני כותב יש תהליכים אוטומטיים, וגם שם התבנית נשארת. אם התהליך הוא משהו שקורה בתדירות כלשהי קבועה וצפויה הוא יישאר וימשיך לעבוד. אם זה משהו שקורה פעם בהמון זמן או בצורה לא צפויה הוא דורש הרבה יותר עבודה. הנה כמה דוגמאות: 1. לקוח שכל חודש עושה ניסוי שיחזור מגיבוי לכל המערכת יעשה את הניסויים האלה הרבה יותר מהר ואפילו בצורה כמעט אוטומטית, בהשוואה ללקוח שעושה ניסוי שיחזור כשיש לו זמן (אפשר למשל לכתוב סקריפט שאוטומטית מרים שרת באמזון, מושך אליו את הגיבוי האחרון, מריץ את כל הבדיקות ושולח מייל סיכום בסוף. סקריפט כזה יכול לרוץ פעם בחודש והכל טוב). 2. לקוח שמחזיק מערכת CI שמריצה את כל הבדיקות כל לילה יריץ בדיקות הרבה יותר בקלות בהשוואה לחברה בה המתכנתים מריצים לעצמם את הבדיקות על המכונות שלהם כשיש להם זמן. בפעם הראשונה שבדיקות נכשלות למשל בגלל שה Chrome Driver מתיישן אנחנו מיד רואים את זה ויכולים לתקן (לעומת מישהו שמריץ בדיקות פעם בכמה שבועות ואז כל הרצה של הבדיקות מחזירה אינסוף כישלונות ואף אחד לא זוכר אם זה אי פעם עבד). 3. לקוח שמתאמץ לבנות תהליכי עבודה מסודרים ב git וכל המתכנתים שם עברו הכשרה לשימוש רציני ב git יצליח להתמודד עם קונפליקטים ושטויות של גיט הרבה יותר טוב מחברה בה אנשים פוחדים ליצור בראנצ'ים. אם שווה לכם להתאמץ כדי לבנות Workflow אפקטיבי, אל תשימו אותו בצד, אל תשימו אותו בהקפאה - השתמשו בו. כל יום, כל שבוע או כל חודש. תהליכי עבודה שלא נוגעים בהם מתיישנים ומחלידים, ואז הזמן שהשקעתם בבניית התהליך פשוט מתבזבז.

ToCode
1 419
# אבולוציה או רבולוציה רבולוציה (מהפיכה בעברית) קורית כשטכנולוגיה חדשה משנה את כל מה שהיה לפניה וזורקת לפח את העולם הישן, ואבולוציה היא מה שקורה כשטכנולוגיה חדשה מוסיפה עוד קומה למבנה שאנחנו מכירים. בעבודה בתוכנה אנחנו נתקלים כל הזמן בשתי התופעות וכל אחת פותחת סוג אחר של הזדמנויות. מהפיכה היא מה שקרה ב 2008 כשפיתוח יישומי אייפון שינה את כל מה שידענו על פיתוח מובייל. מפתחי מובייל מסוימים הצליחו לשרוד את השינוי אבל רבים אחרים עברו לכתוב קוד במקומות אחרים, והמון מפתחים שאף פעם לא היה להם שום ניסיון במובייל נכנסו לכתוב יישומי אייפון ושינו את העולם. מהפיכה דומה קרתה רק כמה שנים מאוחר יותר בעולם פיתוח ווב, כשטכניקות JavaScript מתקדמות קיבלו תמיכה מובנית בדפדפנים. מפתחי ווב וותיקים מצאו את עצמם מחוץ למשחק והמוני מפתחים חדשים שהגיעו מעולמות אחרים השתלטו על המגרש. מהפיכה היא גם מה שקרה (בקנה מידה קטן בהרבה) כש Swift ו Kotlin החליפו את Objective C ו Java בתור שפות התכנות המרכזיות למכשירי אייפון ואנדרואיד. השפות החדשות פתחו את הדלת למפתחים חדשים להיכנס, והניסיון של המפתחים הוותיקים נראה פתאום פחות מרשים. מה שיפה שאחרי כל מהפיכה כזאת הטכנולוגיה ממשיכה להתפתח בצורה של אבולוציה: גירסה חדשה של iOS לא משנה את כל מה שידענו על פיתוח Objective C, אלא מוסיפה יכולות חדשות באותו עולם תוכן. לזרוק הכל ולהתחיל מחדש זו דרך טובה להכניס מפתחים חדשים לתחום קפוא, והמשך פיתוח והוספת יכולות הדרגתית זה מנגנון שעוזר לוותיקים להרוויח יותר מהניסיון שלהם. כשאני מחפש לגייס מתכנת ריילס היום, כמה שנות ניסיון יש לבן אדם זה מדד מאוד מאוד חשוב. ריילס היא פריימוורק ענקית שגדלה באבולוציה ולכן אין סיכוי שמי שעלה על הרכבת הזאת לפני שנה הצליח ללמוד מספיק ריילס בשביל להיות מועיל. לעומתה בפריימוורק כמו Vue, שבדיוק עברה שיכתוב וגירסה 3 שלה שוחררה רק בשבועות האחרונים, אפשר בהחלט להיות מועיל אחרי כמה חודשים של ניסיון. כלל אצבע פשוט כשאנחנו באים ללמוד טכנולוגיות חדשות ורוצים להיות מועילים איתן: ככל שהטכנולוגיה בשוק יותר זמן וגדלה בצורה אבולוציונית כך ייקח משמעותית יותר זמן ללמוד אותה לרמה טובה. לכן כבר בתחילת הלימוד כשאתם בונים לעצמכם תוכנית עבודה שימו לב מתי היתה המהפכה האחרונה שם וכמה זמן הטכנולוגיה גדלה באבולוציה. הזמן הכי טוב להיכנס לטכנולוגיה חדשה הוא כמה שיותר קרוב למהפיכה, בהנחה שאתם יודעים שהמהפיכה הולכת להצליח (וכן יש סימנים - למשל אם יש חברה גדולה שמקדמת את זה או שמדובר ב Rewrite של פריימוורק מוכר).

ToCode
1 419
# לא משחק את המשחק הזה בשיחה שהיתה לי עם חבר יועץ באזור סוף החופש הגדול של 2016 אני זוכר שהוא סיפר שהוא לוקח כמה שבועות הפסקה מהייעוץ כדי להיכנס לעומק לקוד של Angular2. הגירסה בדיוק הגיעה ל Release סופי והחבר הבין שאם הוא ייכנס לקרביים של המערכת ויבין כל שורה בקוד המקור שלה זה ייתן לו הרבה עבודה בשנים הקרובות, ככל שאנשים ייפרדו מאנגולר1 וישדרגו לגירסה 2. והוא צדק בגדול. באותו זמן שהוא למד את אנגולר2 היו עוד עשרות טכנולוגיות אחרות ברמות שונות של בשלות שאפשר היה ללמוד. היו המון אנשים שחשבו שאנגולר1 יישאר איתנו לנצח, שאנשים יפחדו לשדרג, שבכלל ריאקט הולכת להיות הדבר הגדול הבא. הבחירה לעזוב הכל ולהתרכז בלימוד טכנולוגיה אחת היא בהכרח בחירה לוותר על הרבה סוסים אחרים שרצים באותו זמן. לא צריך חודשים בשביל להצליח לכתוב תוכנית Hello World או להבין בגדול איך להשתמש בכלי או אפילו לכתוב משהו מועיל. כשאני בוחר ללמוד משהו בקטנה מהר מאוד אוכל להמשיך לדבר הבא, וזה שאחריו וזה שאחריו. הבחירה להיכנס לקוד המקור של פריימוורק ולהכיר אותה לעומק היא כן בחירה שדורשת השקעה. אי אפשר לעשות את זה עם יותר מטכנולוגיה אחת פעם בכמה שנים וגם אין צורך. אותו חבר הרוויח הרבה יותר מהרבה יועצי אנגולר אחרים, רק בזכות אותם כמה שבועות של התמסרות ואחריהם עוד כמה חודשים של המשך למידה. כשאנחנו מתלבטים לגבי הצעד הבא ורואים המון המון טכנולוגיות מפתות מסביב, שווה לזכור שכל משחק שאני בוחר לשחק בו בא על חשבון עשרות משחקים אחרים שבהם לא אשחק לעולם. קשה מאוד להרוויח אם אני יודע המון המון דברים ברמה נמוכה; הרבה יותר קל להתקדם כשמתמידים בכיוון אחד.

ToCode
1 419
# שכחו רק לספר ש... חבר שלח לי לינק לספריית Server Side Rendering חדשה בשם iSSR. בתוך הדוגמה בתיעוד אנחנו מוצאים את השורה הבאה:
const { html, state } = await serverRender(() => <App />);
אבל בשום מקום באותו דף תיעוד לא מופיעה המילה cache. זה אומר שאם אני לא יודע כלום על Server Side Rendering ורק קורא את התיעוד של הספריה, יש סיכוי טוב שאצליח לבנות קוד SSR בעזרתה אבל כשהקוד הזה יגיע למשתמשים אמיתיים השרת ייפול מהעומס. בחיים מאוד מועיל ומעניין לקרוא תיעוד של ספריות. אבל בשביל שהקריאה תהיה אפקטיבית חשוב להגיע לתיעוד מוכנים עם הבנה של: 1. מה עולם התוכן הרלוונטי של הספריה הזו? 2. איזה ספריות אחרות אני מכיר שפותרות את אותה בעיה? 3. מה הבעיות הכי נפוצות בשימוש בספריות מהסוג הזה? 4. איך הספריה הזאת בחרה להתמודד עם הקשיים שכולם נתקלו בהם? היכרות טובה עם עולם התוכן יכולה למקד אתכם בקריאת התיעוד ולחסוך הרבה דאגות בעת שילוב הספריה החדשה בקוד שלכם.

ToCode
1 419
# שקרים שסיפרו לי על כסף במשחק מריו כולם מתחילים עם 5 חיים. שחקנים טובים יכולים להגיע מאוד רחוק במשחק כמעט בלי להיפסל, ושחקנים גרועים, נו, אפילו אם היו להם 20 חיים זה לא היה עוזר. הם עדיין היו תקועים בשלבים הראשונים. במריו, כמו במשחקי ארקייד אחרים, קל לראות שבשביל להשתפר צריך להתאמן: להיכנס לאותו שלב שוב ושוב, לנסות לחקור את השלב, לעשות דברים קצת אחרת כל פעם. לפעמים האימון רץ חלק ואני מצליח לגלות צינור חדש בלי להיפסל, אבל בדרך כלל משחקי אימון נגמרים בסוף עם Game Over. וזה אחלה. המטרה של משחקי האימון האלה היא לא להגיע כמה שיותר רחוק או לכמה שיותר נקודות. היא בסך הכל להתאמן כדי להיות שחקן טוב יותר - שחקנים טובים מצליחים לסיים את המשחק הרבה יותר בקלות בהשוואה לשחקנים לא טובים. עכשיו בואו נדבר על כסף. כסף הוא לא המטרה במשחק המצחיק של החיים, והוא אפילו לא המטרה במשחק הכלכלי. כולנו שמענו על היזמים שגייסו מאות מיליונים והפסידו הכל, ויזמים אחרים שכמעט בלי גיוס הצליחו לבנות מוצר שמשנה את העולם. מה שהופך יזמים מסוימים לטובים יותר מאחרים זה לא כמה כסף יש להם, זה לא כמה קשרים יש להם, זה לא כמה סטארט-אפים הם הקימו או לא. זו מיומנות ואפשר להשתפר בה. לכן הטיפ היום מיועד לפרילאנסרים שקוראים את זה: כמה כסף הוצאתם או הכנסתם החודש זה מדד די גרוע להצלחה. אנחנו מסתכלים על המספר הזה, כמו על כמות החיים שיש במשחק מריו, רק בגלל שזה מספר שקל להסתכל עליו. אבל אם צריך לבחור השחקנים שיצליחו להגיע רחוק הם לא אלה שיש להם יותר כסף בפתיחה, אלא אלה שיודעים יותר טוב לשחק את המשחק.

ToCode
1 419
בעולמות מקבילים לריילס קונספט דומה כבר קיים בפיניקס (נקרא LiveView), ב Django שם זה נקרא Reactor וכבר התחילו לדבר על זה בעולם של ריאקט עם משהו שנקרא Server Components. האם אנחנו הולכים לראות חזרה לצד השרת בקרוב? עדיין קשה לדעת. אבל הפוטנציאל מבחינת שיפור בזמני טעינה, גודל האתרים ופשטות הפיתוח בהחלט נשמע מלהיב.

ToCode
1 419
# פיתוח יישומי Front End בצד שרת טרנד חדש בפיתוח יישומי פרונט אנד יוצא מנקודת הנחה שקוד ה JavaScript שאנחנו כותבים הפך מסובך מדי, גם בשביל המתכנתים וגם בשביל הדפדפנים שצריכים להריץ אותו, ולכן שווה לנסות להחזיר חלק מהלוגיקה לצד השרת. בואו נראה איך זה עובד ב Rails ואחרי זה כמה מילים על ההשלכות גם במקומות אחרים. ## ריילס ו Stimulus Reflex הספריה StimulusReflex בריילס מאפשרת לפתח יישומי צד-לקוח עשירים ללא כתיבת JavaScript (או עם כתיבת הרבה פחות JavaScript ממה שהיינו מצפים). הארכיטקטורה שלה פשוטה ונשמעת במבט ראשון קצת לא הגיונית: 1. כל לקוח שמתחבר לאתר פותח Web Socket לשרת. 2. כשלקוח מבצע פעולה אנחנו שולחים את המידע המעניין על הפעולה לשרת דרך ה Web Socket, השרת מטפל באירוע ומחזיר קוד HTML חדש ללקוח. 3. הלקוח מחליף את ה HTML שהיה לו במה שהגיע מהשרת. בצורה כזאת אנחנו מקבלים אפליקציית Front End עשירה כמו שאנחנו רגילים עם הפריימוורקים, אבל בלי קוד JavaScript כי כל הטיפול באירועים עובר לצד שרת. לא צריך לשבור את הראש על סינכרון או פיתוח API כי המידע פשוט זמין איפה שהקוד רץ. ## דוגמה 1 - מונה לחיצות קוד? ברור. בשביל זה באנו. אחרי שמסיימים להתקין את הספריה לפי המדריך שלהם אנחנו ממשיכים לכתוב בצד השרת "רפלקס", שזה קוד טיפול באירוע. הנה אחד כזה לדוגמה:
# file: app/reflexes/counter_reflex.rb

class CounterReflex < ApplicationReflex
  def increment
    @count = element.dataset[:count].to_i + 1
  end
end
זה קובץ רובי שמגדיר פונקציה בשם increment. הפונקציה לוקחת מהאלמנט את המאפיין data-count, הופכת אותו למספר ומוסיפה אחד. את התוצאה היא שומרת במשתנה בשם @count. בשביל להשתמש ברפלקס אני מגדיר את המבנה הבא בתוך ה HTML שלי בקובץ ה View:
<div id="counter-demo" data-reflex-root="#counter-demo">
  <button
    data-reflex="click->Counter#increment"
    data-count="<%= @count %>"
  >

    Click Here
  </button>
  <p>You clicked <%= @count.to_i %> times</p>
</div>
יש לנו כפתור עם מאפיין בשם data-reflex שמגדיר איזה רפלקס ייקרא כשלוחצים עליו ומאפיין data-count שנשלח לרפלקס. אני משתמש במשתנה @count בכל הבלוק שבתוך אלמנט counter-demo ולכן הגדרתי את counter-demo בתור שורש עץ הרפלקס. באופן אוטומטי אחרי ביצוע הרפלקס ריילס יבנה מחדש את ה HTML וישלח אותו לצד הלקוח, וקוד JavaScript בצד הלקוח יחליף את האלמנטים הרלוונטים בתוך data-reflex-root בערכים החדשים שלהם. התוצאה כמו שאתם בטח מדמיינים כבר היא מונה לחיצות שמציג כפתור ואחריו פיסקה שמספרת כמה פעמים לחצו על הכפתור. ## דוגמה 2 - השלמה אוטומטית בגלל שקוד הטיפול באירוע רץ בצד השרת יש לי שם גישה מלאה לבסיס הנתונים ולכל המידע של השרת. הדוגמה הבאה ממחישה את היופי בגישה באמצעות רכיב של השלמה אוטומטית. נתחיל עם קוד צד השרת:
class ExampleReflex < ApplicationReflex
  def autocomplete
    search_text = element.value

    @options = User.where("name like 'search_text%'").pluck(:name)
  end
end
בגלל שאנחנו רצים בצד שרת אין בעיה לגשת לבסיס הנתונים ולמשוך משם את כל המשתמשים שהשם שלהם מתחיל בטקסט שכתוב ב input. שומרים את הרשימה במשתנה @options וב HTML אפשר לכתוב את הקוד הבא:
<div id="ajax-autocomplete-demo" data-reflex-root="#autocomplete-options">
  <input type="text" data-reflex="input->Example#autocomplete" list="autocomplete-options" />
  <datalist id="autocomplete-options">
    <%= @options&.each do |val| %>
      <option value="<%= val %>" />
    <% end %>
  </datalist>
</div>
באופן אוטומטי כל פעם שמשתמש מקליד טקסט בתיבה הטקסט נשלח לשרת, השרת שולף מבסיס הנתונים את רשימת אפשרויות ההשלמה המעודכנת ומחזיר ללקוח, שבתורו מעדכן את הרשימה אצלו בצורה אוטומטית. ## מה הלאה צריך לזכור שהגענו לכאן כי קוד ה JavaScript שאנחנו כותבים הפך מסובך מדי: מסובך מדי לחלק מהמתכנתים ולא פחות חשוב מסובך מדי לדפדפנים. היום עמודי ווב טיפוסיים כוללים מספר מגה בייטים של קוד JavaScript, ושיפור זמני טעינה וביצועים הן בין הדאגות הגדולות של מפתחי פרונט אנד. במבט ראשון המעבר לטפל בחלק מהאירועים בצד שרת ושליחת HTML במקום קוד נשמע כמו פיתרון טוב לשתי הבעיות. במכה אחת אנחנו חוזרים לקוד פשוט יותר ויעיל יותר. יהיה מעניין לראות איך פריימוורקים כאלה יסתדרו בעולם האמיתי עם עומס של משתמשים אמיתיים.

ToCode
1 419
# שתי תמונות של הדרכה בתמונה הראשונה נדמיין קהל שמסתכל בשקיקה על מרצה כריזמטי, בסגנון אולם של Ted שמלא עד אפס מקום וכולם מחכים לשקף מעורר ההשראה הבא. בתמונה השניה נדמיין קבוצת אנשים בסדנת נגרות, כל אחד ליד השולחן שלו עם הציוד מסודר ואיזה נגר חביב מדגים ועובר בין התלמידים לתקן את הסגנון. מסיבות שאני לא מבין עד הסוף עולם ההדרכה המקצועית להייטק נוטה בצורה חדה לכיוון התמונה הראשונה. אם זה עובד לכם זה מעולה, אבל שווה לזכור שאם ניסיתם להעביר שעת העשרה בעבודה או הרצאה במיטאפ וזה לא עבד כמו שתכננתם - כדאי לנסות בפעם הבאה את התמונה השניה.

ToCode
1 419
המכשול האחרון ברשימה הוא הסחות דעת וספציפית בלימודי טכנולוגיה מדובר על הנטיה שלנו להרגיש ש"הבנו את הפואנטה" ולהמשיך ללמוד את הדבר המלהיב הבא. אי אפשר ללמוד ריאקט בשבועיים או Front End בחודש. הדברים האלה לוקחים זמן והגעה לרמה מקצועית רצינית זה משהו שדורש פוקוס והשקעה לאורך זמן. קורס אונליין ובניית פרויקט קטן פשוט לא מספיקים. אני יודע שבכל נקודת זמן הדבר-שאני-לומד-עכשיו הוא הרבה פחות מעניין מ-הדבר-המדליק-שכולם-מדברים-עליו, פשוט בגלל קצב השינויים בתעשיה והעובדה שדברים חדשים מופיעים הרבה יותר מהר ממה שלוקח ללמוד את הדברים הקודמים. יחד עם זאת הסחות דעת ומעבר בין טכנולוגיות מבזבזים את הזמן שלנו ומורידים לנו את הביטחון העצמי. כשאתם בתוך לימוד של טכנולוגיה ומרגישים שכל העולם עבר לדבר על הדבר הגדול הבא, שווה לקחת אוויר, לסגור את הרדיט ולחזור לספרים. יהיה זמן ללמוד את הדבר הגדול הבא אחרי שנהיה טובים במה שאנחנו לומדים עכשיו. ## קרדיט מי שהראתה לי את ארבעת המכשולים האלה היא פודקסטרית בשם קלותילד דוסולייה שמעבירה פודקסט בשם changemavie. הפוסט הזה מבוסס על הפרק האחרון בפודקסט ואם אתם מבינים צרפתית אני מאוד ממליץ להקשיב לה ישירות.