למצוא מיקום קוד מקור של מתודה ברובי / ריילס

כתבתי פוסט בבלוג שלי באנגלית על איך אפשר למצוא מיקום קוד מקור של מתודה מסוימת בפרוייקטים של רובי/ריילס.

לעיתים, בגלל Meta Programming וDuck Typing זה יותר קשה ממה שזה נשמע.

הפוסט עודכן פעמיים בעקבות תגובות שקיבלתי בטוויטר. מומלץ!

Find the source location of a method in your project | KensoDev.

אתר מאפס ברובי און ריילס #2 (סקרינקאסט)

כזכור לכולם, בפוסטים הקודמים כתבתי על מיזם חברתי חדש שאני עובד עליו, שבאמצעותו אתרום לשתי קהילות במקביל וכל זה בעזרת רובי און ריילס – איך תורמים לשתי קהילות במקביל עם רובי און ריילס ואתר מאפס ברובי און ריילס #1.

זהו החלק השני בסדרה, שבו הוספנו את מודל ה-User כולל את האפשרות שמשתמשים יבצעו Login, Forgot Password ועוד.

כמו כן, הראינו איך בדיוק מוסיפים טסטים למודלים ואיך מבצעים מיגרציות לבסיס הנתונים.

אשמח לתגובות (גם דרך הפייסבוק) וכרגיל לייקים יתקבלו בברכה גם כן.

תהנו!

Creating a rails application from scratch #2 from Avi Tzurel on Vimeo.

A/B Testing או איך ריילס תעזור לכם להרוויח יותר כסף מהאתר שלכם?

בהתקדמותכם הלאה בפוסט הזה, אתם מצהירים מספר דברים:

  1. יש לכם אתר אינטרנט ואתם רוצים להרוויח ממנו יותר כסף
  2. אתם לא חאפרים ולא בונים אתר אצל חאפרים

טוב, נמשיך?

מהו A/B Testing?

A/B Testing זו בעצם דרך לבדוק את הוריאציות השונות של האפליקציה שלכם ואיך הוריאציות האלה מתפקדות בעיני הגולשים שלכם. מה הייתם אומרים אם הייתי אומר לכם ששינוי כותרת יכול להביא לעלייה של 12% במכירות השבועיות שלכם? מה הייתם אומרים אם הייתי אומר לכם שפונט קטן יותר ושינוי של פסיק בפסקה מסוימת יכול להביא לעליה של 5% נוספים?

אני יודע מה הייתם אומרים לי – הייתם אומרים לי שאני משוגע, ולא רק שהייתם אומרים לי שאני משוגע, אלא שהייתם אומרים לי שאין לי שום דרך לבדוק את זה סטטיסטית וזה לא יעמוד בשום מבחן מתמטי אמיתי.
אתם יודעים מה הייתם אם הייתם אומרים את זה? הייתם טועים.

בעולם התחרותי של היום, עולם שבו יש מוצרים באינטרנט, SAAS) Software As A Service) במחירים שונים ובמקומות שונים יש המון חשיבות למסרים ויזואליים, מיקומם של המסרים האלה ועוד. לפעמים מדובר בדברים בולטים לעין, כאלה שאם תקחו כותב תוכן טוב או מעצב גרפי טוב תצליחו לשפר באחוז ניכר את המכירות שלכם ואת האינטראקציה של גולשים עם האתר. אבל, לא על זה אני מדבר – אני מדבר על השיפורים הקטנים, מיקום של כותרת, מה יהיה כתוב בה וכדומה.

דוגמא ל-A/B Testing במוצר שמכניס מיליונים ויכול להכניס יותר

החבר'ה מ37Signals כתבו פוסט מעלף/מאלף על ניסוי שהם ערכו. הניסוי שהם ערכו דיבר על כותרת ותת כותרת בדף הרשמה לחשבון. זה הכול.
למשל: וריאציה ראשונה
hrhq-signuphead-30day60sec

והוריאציה השנייה
hrhq-signuphead-start30trial

אני יודע, מדגדג לכם על הלשון להגיד שזה לא באמת משנה נכון?

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

עד כאן יפה מאוד, שכנעתי אתכם שזה נכון לבצע A/B Testing וכך תוכלו להרוויח הרבה יותר כסף מהאתר שלכם ולבדוק אפקטיביות של מסרים ואפקטיביות של גרפיקה ועוד ועוד.

אבי, אבי, אבי שכנעת אותי, איך אני ממשיך מכאן?

המלאך על הכתף הימנית לוחש לי שאני חייב לציין שיש דרך לעשות את זה גם בלי ריילס, השדון הרשע מצד שמאל זועף וכועס אבל לצערי, אפשר לעשות את זה גם בלי ריילס :-(

אם יש לכם אפליקצית .net או php או אפילו python אפשר כמובן לעשות את זה באמצעות Google Web Optimizer. זה לא סקסי כמו ריילס ולא מובנה בתוך האפליקציה כחלק בלתי נפרד אבל זה כמובן ולידי לגמרי וניתן לביצוע. אפשר גם לבצע את זה באמצעות Google Analytics אבל שוב, זה לא מובנה בתוך האפליקציה ותצטרכו לכתוב הרבה יותר קוד בשביל זה.

אז עם ריילס זה יותר קל?

הכול עם ריילס יותר קל (ונעים ונחמד וכיף :-) )

מה נעשה עכשיו?

עכשיו אנחנו ניקח אפליקציה מאפס ונבנה אותה ל-A/B Testing. אנחנו ניצור טופס הרשמה, בטופס הזה נשים פסקה של טקסט, ונבדוק איך משפיעה הפסקה הזו על כמות האנשים שנכנסים ובאמת נרשמים בסוף.

נתחיל בלייצר אפליקציה שנקרא לה ab_testing.

rails ab_testing

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

הנה הView שלנו:

<% title "Free Sign up" %>

<p>
	Register below to discover the awsomeness of our website
</p>

<p>Already have an account? <%= link_to "Log in", login_path %>.</p>

<% form_for @user do |f| %>
  <%= f.error_messages %>
  <p>
    <%= f.label :username %><br />
    <%= f.text_field :username %>
  </p>
  <p>
    <%= f.label :email, "Email Address" %><br />
    <%= f.text_field :email %>
  </p>
  <p>
    <%= f.label :password %><br />
    <%= f.password_field :password %>
  </p>
  <p>
    <%= f.label :password_confirmation, "Confirm Password" %><br />
    <%= f.password_field :password_confirmation %>
  </p>
  <p><%= f.submit "Sign up" %></p>
<% end %>

וכך זה נראה בדפדפן:
Registration form

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

לבחור את הכלי הנכון

ישנם מספר כלים טובים לריילס שמתאימים לעבודה הזו, אחד מהכלים האלה נקרא Vanity. אומנם אני לא אכסה אותו בפוסט הזה, הוא דורש עקומת לימוד גדולה יותר, מה גם שהוא דורש Redis. זה כמובן מתאים יותר לאתרים עם נפחי תנועה עצומים, למה שאנחנו נעשה היום זה פחות מתאים. למרות זאת, הייתי ממליץ לכם להעיף עליו מבט כמובן, יש לו המון פיצ'רים וסטטיסטיקות ועוד ועוד.

הכלי שאנחנו נדבר עליו ונכסה אותו יהיה A/Bingo, זהו בעצם Plugin לרובי און ריילס שמבצע בדיוק את מה שאנחנו צריכים.

התקנה

כול מה שצריך בשביל להתקין את הפלאגין זה כרגיל בריילס, להריץ שורת פקודה:

script/plugin install git://git.bingocardcreator.com/abingo.git

לאחר שביצענו את זה, אנחנו צריכים להגדיר את בסיסי הנתונים שישמור את נתוני המחקר שלנו להצגה וסטטיסטקה. מה שאנחנו נעשה זה לייצר Migration:

script/generate abingo_migration

זה ה-Migration שנוצר לנו כתוצאה מהפקודה:

class AbingoMigration10< ActiveRecord::Migration
  def self.up
    create_table "experiments", :force => true do |t|
      t.string "test_name"
      t.string "status"
      t.timestamps
    end

    add_index "experiments", "test_name"
    #add_index "experiments", "created_on"

    create_table "alternatives", :force => true do |t|
      t.integer :experiment_id
      t.string :content
      t.string :lookup, :limit => 32
      t.integer :weight, :default => 1
      t.integer :participants, :default => 0
      t.integer :conversions, :default => 0
    end

    add_index "alternatives", "experiment_id"
    add_index "alternatives", "lookup"
  end

  def self.down
    drop_table :experiments
    drop_table :alternatives
  end
end

לאחר שיש לנו Migration, נבצע Migrate לבסיס הנתונים שלנו (זה אומר בעצם לייצר את כול הטבלאות, שדות וקשרים לפי הMigration שייצרנו לפני שנייה):

rake db:migrate

הגענו לבדיקה הראשונה, יש!

טוב, אז מה שאנחנו בעצם רוצים לעשות זה לבדוק את הפסקה שלנו, את האפקטיביות שלה לעומת פסקה אחרת. אנחנו נוסיף את התנאי הזה בView שלנו בצורה הבאה.

אנחנו עושים את זה על ידי שימוש במתודה שנקראת ab_test שמחזירה נתון בוליאני האם התנאי הוא נכון או לא. המתודה הזו עושה את זה ובדרך גם מזהה את המשתמש המדובר (שניתן כמובן לשלוט על זה, נראה את זה בהמשך)


<% title "Free Sign up" %>

<% if ab_test "signup_paragraph "%>
<p>
 Register below to discover the awsomeness of our website
</p>
<%else%>
<p>
 This is the alternative content
</p>
<%end%>

<p>Already have an account? <%= link_to "Log in", login_path %>.</p>

<% form_for @user do |f| %>
 <%= f.error_messages %>
 <p>
 <%= f.label :username %><br />
 <%= f.text_field :username %>
 </p>
 <p>
 <%= f.label :email, "Email Address" %><br />
 <%= f.text_field :email %>
 </p>
 <p>
 <%= f.label :password %><br />
 <%= f.password_field :password %>
 </p>
 <p>
 <%= f.label :password_confirmation, "Confirm Password" %><br />
 <%= f.password_field :password_confirmation %>
 </p>
 <p><%= f.submit "Sign up" %></p>
<% end %>

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

את השמירה אנחנו נעשה ב-Controller מיד אחרי שמירת המשתמש:

class UsersController < ApplicationController
 def new
 @user = User.new
 end

 def create
 @user = User.new(params[:user])
 if @user.save
 bingo! "signup_paragraph"
 session[:user_id] = @user.id
 flash[:notice] = "You are registered and signed up!"
 redirect_to root_url
 else
 render :action => 'new'
 end
 end
end

אפשר לראות את המתודה שאנחנו משתמשים בה כדי לשמור:

bingo! "signup_paragraph"

עכשיו מוגדר לנו מבחן. התוצאות של המבחן הזה נשמרות בבסיס הנתונים שלנו (צריך לדאוג שבProduction יהיה קאש מסוג כולשהו) אנחנו רוצים לראות את התוצאות שלנו.

צפייה בתוצאות המבחן

אנחנו נייצר Controller כדי לצפות בתוצאות:
ֿ

script/generate controller abingo_dashboard

בתוך ה-Controller הזה, אנחנו צריכים לייבא את המודול של Abingo. מומלץ כמובן שה-Controller הזה יהיה נגיש רק לאחר ולידציה של משתמש אבל אנחנו לא ניגע בזה כרגע.

כך נראה ה-Controller שלנו:

class AbingoDashboardController < ApplicationController
  include Abingo::Controller::Dashboard
end

עכשיו, מה שאנחנו צריכים לעשות זה לייצר Route עבור הצפייה בסטטיסטיקות. זה נראה כך:

  map.abingo_stats "/abingo_stats/:action/:id", :controller=> :abingo_dashboard

עכשיו שיש לנו route מוגדר, בואו ונצפה בתוצאות (אם הserver שלכם פועל, צריך לאתחל אותו):
Abingo Stats

סיכום

נגענו בקצה הקרחון של A/B Testing – גם מבחינת הקונספט וגם מבחינת איך לבצע את זה ב-Ruby on Rails. כמובן שיש עוד הרבה אופציות לבחון, ויש אפשרות לאחד מבחנים תחת כותרת מסוימת וכדומה.
יש דרכים לזהות משתמשים רשומים, לעשות Random של האם יוצג או לא ועוד עשרות שיטות שאפשר לבחון כול מקרה לגופו. האפשרויות (כרגיל) הן בלתי מוגבלות.

ללמוד ריילס כמו זומבי

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

אני חושב באמת ובתמים שהכניסה הזו (הקונספט שלה) היא זו שאשמה בכך שאין יותר מתכנתי Ruby on Rails. להערכתי ברגע שסף הכניסה יהיה פשוט יותר ונגיש יותר, יהיו לנו הרבה יותר מתכנתי ריילס ופחות מתכנתי דוט נט (וזה מצב מעולה בעיני).

נכנסים לעולם הריילס?

משיטוט ברשת מצאתי משהו מדליק שאני חושב ששווה לחלוק אותו ומי שרק נכנס לעולם הריילס ימצא אותו מועיל מאוד.
חברת Envy Labs שמפתחת אפליקציות בריילס וגם אחראית לכול ה Video Tutorials באתר הרשמי של Ruby On Rails הוציאה סדרת Video Tutorials חדשה שנקראת Rails For Zombies מדובר על סדרה של Video Tutorials טובים מאוד ואיכותיים מאוד שעוזרים להכנס לעולם של ריילס יותר בקלות מלעבור על מאמרים באורך 20-30 עמודים.

הנה צילום מסך מתוך האתר, אפשר לראות שלא מדובר בVideo סטנדרטי כמו RailsCasts או כול אחד אחר, הגישה היא קצת אחרת :-)

Screen shot 2010-12-07 at 8.40.00 AM