[直播筆記] 模擬面試要點(主講人:Xdite & Nic)

直播資訊

主講人:Xdite & Nic
時間:6月19日
時長:本次直播總時長預計30分鐘
概要:Xdite & Nic 老師為大家示範面試的正確方式


直播筆紀

為什麼要辦「模擬面試」

  • 很多人技術能力夠,但應答能力不夠;「特別老實」,所以就被電慘了。
  • 「如何勾起別人的興趣?」、「如何答技術題目?」,是很重要的應答技巧。


模擬面試內容

Xdite 老師在模擬面試中問到的問題:

  • 自我介紹,說說當初為什麼想要接觸 Ruby on Rails 這個世界?
  • 從(本科系)到程序開發,為什麼會有這麼大的跨度?
  • 你如何學習 Ruby on Rails?



Xdite 老師的提點:

  • 必須要在前兩個問題就展現出「熱情」跟「人格特質」,接著在第三個問題,提出面試官會好奇的「技術點」
  • 不要講什麼「刻苦練習」。
  • 面試的問題是「一個勾一個」;所以要自己製造話題,讓面試好奇,並追問技術細節。例如:我作過 12 in 12、與其他人協作開發項目等等。
  • 保守的安全回答,反而有可能讓面試官無語,不知道怎麼開展話題。
  • 不要去講什麼老師、培訓班,請把重點放在自己身上!
  • 在 30 秒內完成回答,避免冗長、沒重點。
  • 面試官聽到「補習班」就先扣分了,因為他根本不清楚課程內容;請自己把學習重點講出來,主動暴露「優點」。例如:「參加兩次大賽,因為自己作出好作品而獲獎。」、「在兩人協作中,我擔任主程式,順利推進項目。」。



Nic 版本的面試回答:

  • Nic 提到「Hackthon」,會給人「勇於接受挑戰」、「積極」的野性程序員印象,不但留下好印象,也會讓面試官感興趣,追問 Hackthon 的內容、技術細節。
  • 在陳述學習歷程中,展露出「精進自己,從『原本不會』進步到『巨幅成長,還有成果』」的過程。
  • 留下伏筆「參加大賽,並拿到一等獎」,讓面試官追問「作了什麼樣的項目?」以及項目中的技術細節。


面試要點

  • 「人格特質」比「技術」更重要。
  • 請引起面試官的興趣。
  • 要讓面試官看到你的「人格」,「願意為自己的興趣鑽研技術」。



面試官看重以下兩點:

  • 適合當程序員的特質:對世界有好奇心、熱情,有自己解決問題的能力。
  • 技術問題:回答時,不要留下「拖油瓶」的印象。


連結補充

水平自測:利用這個表單,檢視學習狀況跟目前程度。

[分享] JD Store 魔改大賽複盤 — 協作經驗、各類領悟

前言

如果說上一次 Job Listing 大賽 教會了我:「心態建立」:

  • 拋開虛榮心、妄念,只關注自己的成長,並認清比賽的真正目的:

    • 知識遷移:把基礎技能和知識,實際運用在真實項目上。
    • 逼出潛能:老師和助教給了你魚竿後,你能釣到小魚還是大魚?或是自己開外掛把魚竿升級?
    • 完成一個完整的項目:大賽是我們「讓點子落地」的最好機會。
  • 如何面對競爭

  • 擺脫完美主義

※ Anndo 的 Job Listing 大賽的完整心得請見:[分享] 魔改大賽 — 調適心態、持續迭代

這一次的 JD Store 則是截然不同的一次經驗:

  • 一方面, JD Store 大賽多了很多新的要素:協作、牽涉更多技術的項目主題(購物網站);我們藉此提高了與人溝通、合作的軟實力,以及實現各種前後端功能的硬實力。
  • 另一方面,新的規則跟投票機制,大幅牽動了大賽氛圍。混戰之中,無可避免會掉入情緒坑,但因此得到的全新領悟,也是相當寶貴的一次經驗。

從 5/7 正式敲定了隊友人選,到 6/12 比賽結束,一晃眼就是一個多月過去了。回過頭,才發現已經走了這麼遠;往前看,才知道未來的道路還很長,大賽不過是學習路上的一小個關卡。在進行下一個 Hard 模式關卡之前,藉這篇分享文,作一次 JD Store 魔改大賽心得複盤!



我是怎麼找到我的神隊友 Jimmy Wang?

回憶大賽,最幸運的事情莫過於是我有一個神隊友,也就是大家公認的學霸:Jimmy Wang(吉米王 )。過去我從來不敢想像自己能與前段班的學霸學員合作,更不用說是吉米了。然而,現在回想起來,這份「幸運」也許是有跡可循的。


過去的積累、表現,會形塑別人眼中的「你」。

在討論組隊時,吉米有提到我的「認真」,說道:「在微信群的發言、文章,誰認真,都看得出來,誰頭腦清楚也是。」。而我自己在挑選隊友、評估組隊邀請時,則是會在意對方對於細節的講究與要求。

綜合我們兩人的標準,歸納出下面幾點:

  • 學習態度:是不是伸手黨?如何實踐全棧營的學習(教材練習、ORID、教程、其他分享)?
  • 大腦清晰:你問問題的方式具體與否、發言和文章內容的邏輯、脈絡。
  • 平時習慣:產出的代碼、文字整潔與否、易讀性高嗎?Commit 習慣如何?重視這些細節的人,一般來說自我要求相對高。確保日後合作時,不會因為亂無章法的代碼或個人習慣而卡關。

平日的展現出來的學習態度跟成果、人品,會在關鍵時刻(例如:找隊友),大大地推你一把,讓你獲得你夢寐以求的機會。


積極交流、勇於爭取機會。

Xdite 老師曾經這樣描述全棧營:「你參加的是高品質的 MBA。要去和其他人交流,否則就是浪費自己的機會。要抓住機會啊!」,文班長、吉米也曾多次跟我講到這樣的觀念:「要直接,想要什麼就去爭取。失敗就學取經驗,繼續下一次。」,也因此,我在全棧營的作風,一反常態,不再是過去那個怯生生、總是擔心熱臉貼屁股的自己,盡可能地去爭取自己想要的機會。

更何況,「以程序員的身份,與他人協作,完成一個編程項目」是多麼難得的體驗,眼前又是各方面都可作為學習典範的吉米,我知道自己如果放棄嘗試,事後回憶起來,絕對會後悔莫及。


協作經驗 — J & A 是怎麼將溝通成本降至最低?

目標明確,便能快速決策。

我們在討論時,會先把「目標」確立下來,以此為根據去作決定。當雙方有明確、清晰的共同目標時,便能有效討論,並且快速達成共識。

舉例來說,我們最初各自搜羅購物網站的主題靈感,寫了共 8 個左右的主題,在正式開始討論之前,吉米就寫下了「主題評選標準」。這個標準一出來,基本上一半以上的選項就先篩去了,再就剩下選擇稍加討論,大賽準備期最重要的事項之一:「挑選主題」便立即達成!

無論是挑選主題,還是腦內風暴、發想功能、排版的討論,在進入正題之前,花短短幾分鐘「設立目標、討論事項」,這個動作大大提升了我們的討論效率跟決策速度;而最後作出的決定,因為符合我們的目的和檢視標準,日後也不易生變。


溝通 — 不帶情緒,不隱瞞實際想法和意見。

跟一些同學聊到「協作」遇到的坑時,聽到很多「我想如何如何,但我不知道他是怎麼想的。」這樣的句型,這也讓我回憶了一下我跟吉米之間的協作過程,似乎一次也沒有過這樣的念頭。

最好的溝通,就是「將內心的想法,直接表達出來」;把話憋在心裡,隊友永遠不會知道你的看法是什麼,久了也會憋出內傷,產生一些不必要的情緒。而接受意見的一方,千萬不要將反饋視為「批評」或是「不滿」;如果你的作的東西真的是完美無缺,隊友不會閒閒沒事、刻意找碴。

如果溝通中,反饋的內容「具體、有料」,不但能讓你的意見更容易得到採納,兩人都能因此受益。例如說,可以像這樣建議:

  • 前端視覺:

    • 手繪排版,或是在 Pinterest 上找貼近自己想像的範例、真實網站的樣式,提供給對方。並說明為什麼你覺得這樣子好,試著分析、描述理想樣貌跟目前作品之間的差異。
    • 有想法的人,直接動手調出一個版本,再給對方看,尋求意見和同意。
  • 後端功能:

    • Models 的欄位、關聯如何設計,未來會較好維護及擴充。
    • 以「真實項目」的網站體驗流程、後台管理需求去思考、檢視目前成品,有沒有什麼功能設計是可以加強,讓整體更貼近現實生活中的需求。
  • 編寫教程:

    • 教程的架構、文字易懂與否,重點內容的標題可以再用 Markdown、HTML 語法 加粗或上色以達到強調效果。
    • 是不是可以加入一些前言(大家常遇到的狀況、這篇教程要解決什麼樣的需求)?讓讀的人有共鳴、能想像運用情境。
  • 個人狀態:

    • 如果狀態不好,我們有什麼調整方式?冥想、深呼吸、切換任務,或是放自己一、兩天假。

簡單來說,就是:大膽提出意見,虛心接受指教;同時不斷迭代自己的表達能力。


行動力

從項目推進、上線,到後期的撰寫教程,我們可以說是「J & A 兩人同心,其利斷金」,合力完成了很多事情,過程非常流暢。這樣的協作默契,與其說是來自兩人本身就很合拍(總不能歸因於我們都是台灣同鄉!),不如說是因為「行動力」意識到任何項目需求,就立即提出,兩人主動安排自己可以負責的任務、分頭執行,並互相照應。

像是 5/21 上線當天:

  • 吉米:快手快腳地幫第一版作品進行功能和頁面的收尾、修正(神隊友簡直在閃閃發亮啊!),寫 Logdown 簽名檔用的 HTML,幫網站截圖、準備 JD Store 大賽作品頁面會用到的截圖和敘述。
  • 我:完成文案最終潤飾、推上 Heroku 後,緊接著處理正式端的網站內容;代碼的部分則改一些新發現的 bug、確認語系 yml 檔。開賽前一小時,負責寫 J&A SELECT 作品介紹 的文字部分,以及 GitHub 專案 頁面會顯示的 README.md。

上線前的準備工作如此繁雜、細鎖,但只要彼此執行力夠、積極採取行動,即使事前完全沒有討論或刻意分派的任務,也還是能高效完成。還要有一份「為隊友設想」的心情,不斷問自己:

  • 「現階段,我該怎麼參與、能作些什麼貢獻?」
  • 「圖 / 文案 / 技術支援,隊友有什麼需求?」

當雙方都採取主動參與的姿勢、設身處境的心態,就能很直覺地找到各自當前的任務,項目的推進自然水到渠成,解決「永遠在等對方」的窘境。


自身成長

Job Listing 大賽留下的遺憾,透過 JD Store 大賽來彌補。

上一次大賽,雖然收穫很大,得到很多支持跟讚美,甚至對於當時的實力跟招聘網站的作品水平來說,是有點多得太多了,也因此我最後陷入莫名的低落。這樣「心虛」的情緒,是源自於「成長不夠」。除了開發便宜行事,很多標配功能沒作,也不完全滿意自己的作品(主題、完整度),所以就算得到好的名次、獎品,也開心不起來。

JD Store 魔改大賽 5/22 00:00,上傳系統開放當晚,發現自己心態有很大的轉變。原本我跟吉米都希望能秒上傳、當第一個上線的作品,後來因為 VPN 上傳速度太慢而重來,沒達成頭香的成就;但意外的是,我竟然絲毫不以為意,腦中想的都是:「沒關係,我很滿意我們共同完成的 J & A SELECT 第一版樣貌!」。心情莫名輕鬆、滿足,將比賽的事情徹底拋到腦後,因為我知道我已經了結了前次大賽留下來的很多遺憾,跟著神隊友吉米,我們一起作到:

  • 挑了一個彼此都喜歡、有想法的主題。
  • 靠著明確的目標和分工,即便兩人的狀態都不好,還是達成了將「比賽一開始就發佈一個完整的作品」的階段性目標。
  • 克服曾經懼怕的技術難題,實現當初沒作成的標配功能。

自己貢獻了什麼、如何協作、從隊友的態度和代碼中學到什麼、作品有沒有朝著目標演進,這些經驗跟體悟才能讓心裡真正踏實和滿足。


硬實力成長。

後端功能 — 脫離教材、獨立實作。

Job Listing 魔改大賽,我尚無法完全擺脫對教材的依賴,網站基本框架也是遵照教程、按步驟開發。這一次魔改大賽,我跟吉米在腦內風暴、發想功能時,便針對每一個部分,把 Models、Gems、實作方向,通通寫下。這樣簡單的一個討論環節,卻讓我腦中多了一張全新的「功能實作藍圖」,而不再是參照教材,一個指令、一個動作。

前端排版 — 「觀察/吸收」、「刻意練習」、「遷移技能」,三階段克服弱項。

第一次大賽結束後,我對於「如何利用 Boostrap 的網格系統(Grid System)達到自適應」、「CSS 屬性」,都還是一知半解,多半是腦袋一片懵、靠土法煉鋼弄出自己想要的版面。JD Store 大賽前期有大半時間都在搭建作品的毛胚屋,前端交給吉米去裝修;直到我們切換任務、撰寫模板教程時,我才真正把前端的能力建立起來。

我的學習套路是這樣:

  • 階段一:「觀察/吸收」;小幅修改細節,改改看、玩玩看,熟悉前端代碼、觀察變化。

    在神隊友已經建立的 CSS/HTML 基礎上去作改動;如果你跟隊友的前端能力都尚未成熟,先別絕望,你還是可以將前端高手(如吉米、一期的陳俊鴻學長)的專案 Clone 至本地進行修改。在作品上線之前,我陸續調整了一些前端細節:Navbar/footer 的顏色及樣式、Hover 的文字顏色/底色和效果統一、重新設計 Logo(替換字型、利用 CSS 加圓框)。雖然只是針對小地方微幅調整,但其實這是很好的前端入門方式:

    • 在前端強者的代碼基礎上修改,用「只是玩玩」的心態去修改,不易產生挫敗感或抗拒。
    • 閱讀代碼,觀察前端套路及訣竅:
      • Views 檔案中的 HTML 架構安排。
      • CSS 屬性命名規則。
      • 如何設置通用樣式以達到 DRY(Don't repeat yourself),讓 CSS Class 易於維護、使用。
      • 熟悉常用 CSS 屬性。
    • 過程中,了解「輸入什麼會得到什麼」

      ※ Nic 過去在直播中有叮嚀幾個前端學習心態,「『輸入什麼會得到什麼』才是學習的重點,有過多的糾結會絆倒自己。」便是其一;如果你忘記了、再次陷入糾結,可以利用這篇直播筆記:[筆記生肉][圖解] 如何參加魔改大賽(主講:Nic)

  • 階段二:「刻意練習」;練就如何從 0 開始,兜出自己要的排版、樣式。

    有了階段一的 HTML/CSS 前置知識後,再進一步挑戰自己,從 HTML 到 CSS,一步一步組構一個頁面:

    • HTML 佈局:規劃頁面主要板塊、自適應,預先寫下 Class 名稱。
    • CSS 樣式:用佈局時就規劃好的 Class 名稱,撰寫 Class 的 CSS 樣式內容。
    • 客製細節:類似階段一。

    你可以替自己安排一些練習方式跟限制:

    • 練習作一個只用到 HTML/CSS 代碼的靜態頁面。強調「只用到 HTML/CSS」,是因為練習重點在「前端」,所以把後端代碼的需求降至最低。以製作「商品列表」的前端模板為例:

      ① 終端機執行 $ rails g controller products 後,在 app/controllers/products_controller.rb 中加入 index 的 action,
      ② config/routes.rb 中用 get "/products/index" => "products#index" 設置路徑。
      ③ 在 app/views/products 裡新增 index.html.erb,就可以動手作一個簡單的靜態頁面了。

    • 抄其他作品的前端代碼時,限制自己不能整段複製貼上;強制自己按照上述的:「HTML 佈局 → CSS 樣式 → 客製細節」逐步添加。才能避免「我感覺自己一直在抄代碼,但不知道自己在抄什麼。」、「抄完就忘。」這類狀況(Xdite 老師、Nic 直播常被問到的高頻問題)。

  • 階段三:「遷移技能」;回答問題、教人,驗證所學。

    作品好看,或是有產出前端相關的教程,自然會吸引一些同學來問問題;或是逛逛交流論壇、Slack、參加 Global Team 的線上 Meetup,主動尋找問題。當面對同學問問題,比起提供大致方向,我會傾向「利用問題,再作一次練習」把被問及的每一個「問題」當作機不可失的「練習機會」。

    例如 Max 之前傳來他想要的商品列表的樣式,說在實作前端頁面時遇到問題,我便利用 Gist 寫了一個簡單的架構給他、附帶註解說明。練習、實作時,人往往會不自覺選擇自己熟悉的佈局、樣式。因為如此,來自其他同學的問題,成了寶貴的「練習題」;把握每一次機會,分析問題、思考解決方案,讓自己充分調動技能,並檢查自己有無知識盲點。

教程撰寫能力 — 寫一篇「傻瓜都能懂」的教程,是最好的學習方式之一。

我跟吉米對「教程」有幾個共同的標準,我認為是這樣的自我要求,讓「提取練習」成效更顯著,而寫出來的教程也獲得不錯的評價。

我們在撰寫教程時,一定會考量:「無論程度,只要照著教程,一定能懂、跟著步驟實現。」。前端效果、後端功能,在自己的項目實現後,為了確保所有人(或至少全棧營的學員)能跟著實作,我們的習慣是:利用教材範圍的基礎框架,重新實作一次,或甚至在教程寫出來後,再按照自己寫的步驟作一遍;藉此確認教程中的步驟、指示是否明確。

為了達到「教程可操作性高」而養成的習慣,讓我們多了一至兩遍的練習,形成很深刻的記憶;而這樣作,也是對使用教程的讀者負責。

※ 整個全棧營的學習期間,我撰寫的系列教程、資源、筆記,請見:


透過幫助別人、解決別人的需求,產生滿滿的動力與自信。

文班長開設的全棧營鐵血群,讓我跟吉米有機會與其他同學(我們的協助對象:李慧)接觸,幫助她的隊伍將 作品 推上線。搭上線後,我們馬上開了一次線上會議,討論時意外發現,我跟吉米習以為常的「協作方式」,是可以幫助到其他人的。

而當我們苦思教程主題時,也從跟協助對象的聊天中,了解到大部分同學可能會有的「需求」,這其中,又以「前端」的需求最為迫切:「作品醜,但又不知道該如何寫出漂亮的前端,所以遲遲不敢發佈作品。」。所以吉米立刻提議製作一套前端模板,將購物網站的三大主要頁面,供大家使用;兩人分頭製作了 Landing Page 以及商品列表、商品資訊頁,J & A 的最受歡迎教程就此誕生:

※ 我跟吉米所寫的系列教程,請見:【JA魔改秘笈】實用秘笈列表

我們其實不自覺地實踐了 Xdite 老師在 < MVP 與 PMF > 直播 所說的:「做一個關心他人需求的人,在幫助的過程中就能尋覓到『剛需』。」

也許在外人眼中,我跟吉米都算是不差的學員(吉米是大家一致認同的學霸),但事實上,我們常常缺乏自信;都太理性,自我認知過於清晰(知道哪裡不會或作得不夠好),所以經常自信不足;旁人如果給我們的評分是 85 - 90 分,我們自己東減西扣,可能會覺得自己只有 65 -70 分。也正因為如此,「與人產生聯繫、產生價值」這件事對我們來說格外重要。多多去找人交流、伸出援手,才會發現自己是有能力幫別人解決問題,也才能建立信心。

藉著這次魔改大賽,重新領悟了「『教』是最好的『學』」這個道理。「教人」、「寫教程幫助別人」,不僅僅是最好的提取練習,也是最好的自信來源。



比賽心態總結 — 關於名次、投票和拉票。

只關注「操之在己」的事。

在萬維鋼的得到專欄讀到一篇文章 < 日課 196 | 斯多葛派哲學的安心之法 >,裡面提到的心態控制,非常適用於兩次大賽。

斯多葛控制二分法指的是:將事情分成「能控制的」、「不能控制的」兩種;我們應該只關注「能控制的」,也就是那些操之在己的事。個人的目標,同樣可以分為「外界目標(不能控制的)」和「內部目標(能控制的)」:

  • 外界目標:設立的目標有過多自己無法控制的因素,把希望寄託在外界目標,容易產生各種焦慮不安的情緒。以大賽來看:「拿到第一名」、「得到獎品」,這其中可能就牽涉到:規則異動(前面幾天不開放投票、微信一鍵投票)、VIP 學員的投票等等,各種你無法掌控的變因。
  • 內部目標:自己可以控制的。魔改大賽,我們最能把握的是什麼?不就是「協作,作一個完整的作品。」這個老師反覆提醒的最終目標嗎?

既然都參加大賽了,誰不想贏?誰能夠完全沒有得失心?我們無法徹底根除慾望和好勝的心,但我們可以轉換心態:「消除慾望這個要求實在太高了。並不是沒有慾望,你想要什麼,可以!但是你要把注意力全部集中在自己能控制的這部分上。」


反思自己的投票心態。

上一次 Job Listing 大賽,留下遺憾的部分其實還包括了:「我有票,卻沒有投給我很欣賞的實力作品。」。例如當時韵兒爸爸的 <尋找匠人> 和黃鴻亮的 <全職小夥伴求職網> 都是非常出色、前後端面面俱到的高水平作品,眾人有目共睹;然而,我最後還是把票留給了其他學員。前陣子,重新反省了當時的心態;不敢把票投出去,其中一個原因也是因為「競爭激烈、怕票數被超越」,而因此不敢去肯定好作品。這是什麼弱者的小人心態?相當可恥、不堪,真想狠狠賞當時的自己幾個巴掌。

這一次魔改大賽,果斷投票。這不是因為上一次沒有投,而這一次「補投票」;是打從心裡激賞韵兒爸爸的自虐精神跟過人的設計品味,以及黃鴻亮的技術硬底子(這樣的死嗑精神何嘗不是一種自虐精神?)。

好作品,沒有道理不給予實質的支持!投完票後,心情都莫名愉快,因為這一票對得起良心。往後與這些優秀同學的互動交流,也讓我更確信這個道理:面對實力之作,選擇「肯定」、「交流」得到的收穫,絕對比選擇「敵視」或「忽視」來得太多、太多了,心裡也舒坦。


重視手上的每一張票,將票的價值最大化。

VIP 學員的 1 票等同於「5 票」,而每位 VIP 可以投給 10 個作品。把票留著,跟別人「換票」,當然可以,但這無形之中也會錯失一些東西。

就以上一次 Job Listing 大賽為例,起初我也是不敢看學霸吉米的作品,生怕玻璃心碎裂;然而,看了他的作品 職贏網,再看看 GitHub 代碼,頓時佩服得五體投地!不但瞬間得到了很多功能實作上的思路、解決了自己遇到的問題,還收穫了清楚的註解方式。太震撼了,馬上奉上手上的一票,加了微信、誠心討教,就此開始了與吉米的交流。如果我當時選擇的把票留著、與其他學員換票,我錯失的恐怕有一個兆那麼多。(借用 Nic 的梗)

慎重投票,你可以:

  • 藉投票,與學霸或你欣賞的學員交流(技術類的問題或思路,學習方式、心態),絕對獲益良多!
  • 鼓勵優質教程,或甚至許願想要知道的主題。J & A 魔改秘笈的主題,很多都是取自支持群眾的反饋。
  • 鼓勵踏實迭代的認真學員。

與人「換票」這個行為所得到的,終究就是票而已。


韵兒爸爸:「成為真正的大神後,再去接受更多鮮花和掌聲吧。」

比賽後期,我們採用的拉票策略是:

這樣的策略,就大賽期間的票數增長跟最後的比賽結果來看,成果相當有限,兩人都感受到很強烈的無力感。比賽最後兩天,索性放寬心,不再積極拉票;就在這時,看到韵兒爸爸的微信寫到:「成為真正的大神後,再去接受更多鮮花和掌聲吧。」,更是徹底釋懷了!

因為作品品質、教程、平時的幫助,而真正打從心裡認可我們作品的學員、親友已經給予投票支持了,這樣的票拿得心安理得。至於沒有投票的學員,或是素昧平生的人,就無須強求了。況且,現階段,無論是實力,還是作品,都還有一些不足之處(部分功能還是會有難解的技術難題、各種可以讓體驗更好的優化項目);把注意力拉回自己身上,「不讓未來的妄念影響當下,我只純粹關注當下的目標」。成長、銳變後,升等至更高的水平後,還怕得不到鮮花與掌聲嗎?


結語

二期 VIP 學員自我介紹的帖子 中,我在 3/25 這天留下了自己的學習目標:

  • 透過全棧營的學習讓自己脫胎換骨;我所想實現的「脫胎換骨」,指的是:用正確的學習姿勢、心態,紮實地收穫一門專業(Ruby on Rails),讓邁向的 30 歲的最後一哩路上,充滿更多可能性。而這陣子在閱讀過去的學員分享的全棧營心得,很多人都有提到 60 天帶來的「自信」,這也是我所欠缺的,所以我想貪心地在「脫胎換骨」的定義上多加一個:成為一個自信的人。

經歷了全棧營的一切:兩次魔改大賽的歷練,與神隊友以及眾多優秀且真誠的學員交流;藉著師長、前輩的提點,一次又一次用力地刷洗三觀,提起勇氣跨出自己的小世界。我敢說,我確確實實地實現了自己的學習目標。


最後,感謝我的神隊友吉米,願意包容我在技術、心態上的不足;總是能在我身陷情緒大坑時,伸出最關鍵的援手。跟你組隊,是我在全棧營最大的收穫。

[直播筆記] 比完賽的你該如何再次成長?(主講人:Nic)

直播資訊

主講人:Nic

時間:6月12日

時長:本次直播總時長30分鐘。

概要:為期三週的比賽結束後, Nic 會教你如何保持成長速度,做個更厲害的編程手。

直播筆紀

學完後一個月,沒再加強記憶,等於沒學!

  • 打鐵要趁熱,請即刻復盤。可以休息一、兩天,但要盡快開始,切忌擺爛!
  • 學完後一個月,沒再加強記憶,等於沒學!所以複盤很重要,要記下:「作了什麼?」、「學了什麼?」。
  • 無論有沒有參賽,都應該要作複盤。沒有參加比賽的同學,可以反省自己為什麼沒參賽或從有參賽的同學身上觀察到了些什麼。


未來學習方向

贖罪(基礎不夠、作業沒作的同學)

  • 雖然老師們會建議「先參賽再說。」,但基礎薄弱的同學在比賽後,請務必利用瑣碎的時間,趕緊複習教材。
  • 把選修課程(e.g. 百寶箱)補上,上傳作業、GitHub。

全棧營提供的支援

  • 每週釋出新的教程。
  • 求職手冊、自我評測水平。
  • 微信求職群,門檻:
    • 參加過兩次比賽。
    • 完成作業進度。
    • 有複盤心得。

聽完直播後,你這週該作的三件事!

  • 寫複盤。
  • 打基礎、新教程練習。
  • 看直播、參與 Meetup。

一定要作,少作就錯過幾個兆!


Q&A 時間

  • Q: 雖然知道 Google 質量高,但過去習慣用百度,英文又不好,所以有點排斥。
    A: 應該是要克服困難,而不是排斥「困難」、只享受「簡單」。如果你想當一個稱職的程序員,Google 絕對是一定是一個必備技能。

  • Q: 老師,對 RoR 的語言結構不清楚,是否該系統去學?
    A: 學習是 Xdite 老師說的「拼拼圖」,沒有所謂的「系統」,沒有必要把每一個細節都搞清楚,應該是要把當下需要的東西搞懂。蒐集越來越多有用的拼圖、放在對的位置,這就是一套系統。

  • Q: 需要買書嗎?
    A: 非必要,但可以試試看。

  • Q: 學到什麼程度才能靠編程吃飯?
    A: 編程的靈魂是「解決問題」。要能靠編程吃飯,你必須要有這樣的能力,實作出解決問題的方案。(e.g. Nic 老師自己寫了看盤的 gem。)

其他重點

  • 不要因為「其他人有作過類似東西」而不去作,人家作是人家學到,但你還沒學到。
  • 如果有 Javascript 的底子,可以直接搜尋、去學框架(e.g. vue.js)。如果你是新手,不建議先碰 Javascript。
  • 初期寫代碼時,寫爛沒關係,只要能動就好。不要一開始就要求完美,會非常痛苦。


推薦資源

[直播筆記] 你應該掌握哪些基本功(主講人:Xdite)

直播資訊

主講人:Xdite 老師
時間:6月8日
時長:本次直播總時長32分鐘。
概要:複盤時間 — 你應該掌握哪些基本功?


直播筆記

為什麼要辦這個大賽?

  • 基礎技術總複盤
    逼你遷移所學的知識和技能;「學編程是要拿來用的。你不但要用,還要用得完整!」

  • 協作能力的鍛鍊
    程序員無法長久進步,是因為總是自己來;然而,自己獨立作業很容易有盲點。「協作」可以讓你察覺不足之處,知道自己的短處後,才有辦法加速學習、加強能力。

參賽手冊其實就是「項目指南」,讓你知道怎麼樣從頭至尾完成一個項目。請列印下來,並反覆練習手冊中的每一個動作。


你應該掌握哪些基本功?

  • 如果你感到慌張、覺得自己實力薄弱,請利用手冊來檢視目前的水平,執行每一個步驟。重點在於「你有沒有辦法不加思索地用?」,你要有辦法用,你才有辦法講出其中的道理。不是教材學完就畢業了!「能不能用?能不能快速地用?」才是門檻。

    舉例來說,你需要練:

    • CRUD
    • 搜尋能力;有沒有辦法精準地下 Google 關鍵字,快速找到需要的解答和資源。
    • 加快寫功能的速度(e.g. 3 小時 → 30 分鐘)
    • 提取練習;寫文章、教程。
  • 「業餘」、「職業」的差別,就在於「不加思索地用」。

  • 鼓勵大家寫 ORID、教程,是因為寫過就會產生深刻印象,是「提取練習」的一種。作最多提取、複盤的人最後都成了大神。(e.g. ihower、Xdite 老師,兩人都是在程序員時期有「複盤練習」好習慣。)

  • 自信、變強,都是靠不斷練習、壓縮每一次的時間。任何一個「你不熟,但是上次作得出來的功能」,在下一次,你能用「一半」的時間作出來,這才是職業標準。

  • 項目的「標配」(e.g. Landing Page)不能不熟!不然你很容易陷入絕望。作產品時會有很多基本的「業務邏輯」,基本的都不熟了,更何況是不熟的?所以職業要求是:更加熟練、更快。

  • 針對一個技能,反覆練習、提高熟練度,你就會產生「洞見」;一旦有了洞見,你就會發現自己少了很多恐懼。

  • 「學編程」不是勳章,不是達成成就後就結束了。如果沒有刻意練習和提取(做一個落地的項目或寫文章),最後還是會一場空。要掌握一項技能,重點還是「實作」!

  • 很多學員都還是「表現型人格」,自我滿足,學一學就覺得「我會編程了」。然而,所謂的「會編程」,應該是要能完全掌握基本動作。


為什麼「新手」無法升級為「高級新手」?

  • 為什麼很多人會卡在「新手輪迴」?最可怕的輪迴,就是重複「新手期錯誤」,卻以為自己辛苦練習、得到很多經驗值,但其實都是錯覺,是自我滿足。
  • 成長 = 下一次作同樣的事情,更快、更像天才。

  • 參加大賽不是「交作業」,而是透過大賽,發現自己的「不足」。發現缺什麼,就去練什麼。練習的定義,不是從基礎作(例如從頭作購物網站),而是將單一動作練得更快。


一定要作的兩個作業

  • 大賽複盤(1000 字)
  • 設計大賽手冊(PDF 檔),檢視自己的知識點。


Q&A 時間

  • Q. 老師當年為什麼要學 Ruby on Rails?
    A. PHP 作項目太慢了,Rails 可以快速開發、有很棒的現成套件,學習起來很有成就感,也會有更多的時間用來學習其他新的事物。

  • Q. 不理解代碼原理,不懂為什麼要這樣寫;對代碼的觀念還是很模糊。
    A. 多練個幾遍。另外就是,你們都犯了「不敢改」的毛病!要改裡面的動作,改壞它!修壞掉的東西,你就知道背後的原理了。

  • Q. 找不到問題的解答,覺得很疲憊。
    A. 找不到解答當然會很疲憊,這是常態!但要積極去找出「問題的邊界跟原因」,然後寫成教程,加快自己下一次實作的速度。
    編程之所以會讓人痛苦,是因為沒有標準答案,只有「接近標準答案的答案」;有時候你找得到,有時候你找不到,這都是正常的。如果你感到痛苦,表示你正在成長,這就是「成長痛」!

  • Q. 與隊友協作、溝通時,理念有衝突,有很多讓步與妥協。哪些是我們該堅持?哪些是我們該妥協的?
    A. 試著再作一個產品,堅持你原先的理念,然後看會不會成功。當時不作了,未來也不作了。不是這樣的!就算讓步、決定採用對方的點子,事後還是要去實現自己的點子,才能驗證自己的想法對不對。如果成功了,就能打對方臉;就算失敗了,也是很好的學習。

  • Q. 有沒有官方寫的功能實作教程?
    A. 教程有一些東西不寫,是希望你自己 Google 寫出來!你要自己有「求知慾」,如果你老是等別人的答案,你在編程的世界是會死的。不管教程再完整、詳細,都不可能 100% 滿足你的需求。你自己本身要有「好奇心」,才是好的學習節奏;你不可能永遠都在等別人給你完美的教程,你如果不行動,就不會成長。

【JA魔改秘笈】Heroku 實用指令彙整(緊急狀況必用的復原版本、多人協作)

關於這篇彙整文章

這個畫面,曾經傷透了多少人的心...

  • 辛辛苦苦搞定了本地端的新功能,但一推上 Heroku 就報錯了!找不到問題,但總不能放著掛掉的網站不管吧?腦袋糊、心態炸裂,卻又不能休息。硬著頭皮搶修,最後只弄出一堆髒兮兮、於事無補的代碼。
  • 創建 Heroku App 時,順手用了 $ heroku create,隨機給的域名意味不明啊!想換域名卻又怕麻煩、會出問題。
  • 隊友的代碼內容有問題,但我是負責推 Heroku 的人;怎麼樣讓隊友自己看 Heroku Logs,然後自己修、自己部署?
  • 「那個指令叫什麼來著...」,偷懶沒有紀錄,每次需要時,都得再回到交流論壇跟學霸的 Logdown 找指令。

過去這段時間,在 Heroku 正式端遇上不少坑,所幸後來知道了「Heroku 版本復原」這一招,日後不再因為 Heroku 部署而緊張兮兮,就算遇上報錯,也能從容應對。這篇文章,除了為大家提供「Heroku 版本復原」、「Heroku 多人協作」的方式,也蒐羅了一些實用指令,供大家收藏、使用。

希望這篇彙整文能幫助大家克服內心深處對 Heroku 部署的恐懼,以及節省四處查找的時間(生命誠可貴)!

--

  • 本文目錄:

    • Heroku 部署上線
    • 查看設定 & 歷程
    • Heroku 正式端資料
    • Heroku 版本復原(*如遇緊急狀況,實用!*)
    • Heroku 多人協作
  • GitHub 簡潔版
    供大家收藏,日後查詢使用,歡迎 Star、Fork。


Heroku 部署上線

註:上線前的 Gemfile 文件的必要修改,網路上、全棧營教材中都有很詳盡的幫助文檔,這篇教程便不再贅述。

  • 創建 Heroku App,並同時命名。
    $ heroku create <專案名稱>

  • 重新命名 Heroku App。
    $ heroku apps:rename <新的專案名稱>

  • 將主幹(master)進度部署至 Heroku。
    $ git push heroku master

  • 將分支(branch)進度部署至 Heroku。
    $ git push <分支名稱>:master

  • 執行所有 Migration。
    $ heroku run rake db:migrate


查看設定 & 歷程

  • 檢查專案的遠端路徑( GitHub、Heroku)。
    $ git remote -v

  • 查看歷程(Logs)。
    $ heroku logs


Heroku 正式端資料

  • 使用遠端 Rails Console,可用於:新增或修改資料,操作方式與本地的 Rails Console 相同,輸入 $ exit 可以跳出。
    $ heroku run rails console

  • 利用 seed.rb 檔案內容創建資料。
    $ heroku run rake db:seed

  • 清空資料庫
    $ heroku pg:reset DATABASE


Heroku 版本復原(*如遇緊急狀況,實用!*)

將版本推上 Heroku 後,遇到讓人絕望的 "We're sorry, but something went wrong." 報錯訊息,但一時之間又無法查明原因、排除問題;這種時候,你可以執行以下步驟,先將網站恢復成能正常運行的版本。

Step 1. 查看過去的部署版本

輸入後,終端機會列出所有的版本號(每一次推 Heroku 會是一版),找到要倒回的版號。

  • 查看部署歷程。

    $ heroku releases

    ----------
    從版本號歷程,你可以看到幾個部分:
    。 版本號:下圖的淺藍圓圈處。
    。 部署內容:下圖的黃色方框處,範例截圖中的 Deploy 23172a7323172a73 這一串英數,就是該版本的最新 commit 的編號。
    。 部署者
    。 日期 / 時間

Step 2. 將 Heroku App 復原至該版本

接著只要利用指令,倒回至該版本的內容即可。

  • 將 Heroku 復原至過去的版本內容。

    $ heroku rollback <版本號>

如果要取消這個改動,訊息也很貼心地告訴你 "To undo, run: heroku rollback <版本號>",照著執行即可。


Heroku 多人協作

多人協作時,要讓其他開發人員一起參與 Heroku 的部署,可以照著以下步驟:

Step 1. Heroku App 的擁有者(Owner)將該人員加至協作者(Collaborator)名單

  • [方法一] 終端機執行指令
    $ heroku access:add <電子郵件地址>

  • [方法二] 前往 Heroku,選擇 App 後進入 Access 設置。


Step 2. 協作者在本地設定 Heroku 遠端路徑。

協作者會收到一封 Email,通知已經被加入協作名單。這時候只要為本機的專案添加 Heroku 的遠端路徑,就可以參與部署了。

  • 新增專案的 Heroku 遠端路徑。
    $ heroku git:remote -a <專案名稱>


補充 — 協作相關指令

  • 瀏覽擁有權限的協作成員名單。
    $ heroku access

  • 移除協作成員。
    $ heroku access:remove <電子郵件地址>




有任何開發上的問題,都可以透過 Slack:xbearx1987、anndo-2 找到吉米或我,我們很樂意為你解答。

如果你覺得教程對你有幫助,希望你能至我們的作品 J & A SELECT投下寶貴的一票!你的投票,代表的是對好作品、好教程的支持與鼓勵,也會成為我們持續分享的動力。

【JA魔改秘笈】Seeds.rb 越來越肥怎麼辦?兩個步驟實現「執行指定檔案,生成數據」

關於這篇教程

  • 使用者、商品內容、類型 / 分類等資料,通通塞在 Seeds.rb,一拉就是幾百行代碼。再多註釋,也還是理不清這一鍋大雜燴。
  • 執行 rake db:seed 時,因為資料龐大,運行到天荒地老。一個小地方錯誤,又得認命去撈代碼、修正,再重來。
  • 網站上線後,添加了新功能、Models,總不能再次利用 Seeds.rb 來建立數據吧?舊的內容要先註解掉?暈了。

如果你也遇過上述狀況,有過「唉,如果能執行部分內容就好了!」的心聲。相信我,你並不孤獨!
這篇教程為大家提供一個解決方案:為專案設置多個用來生成數據的 .rb 檔案,並指定要運行哪一個檔案。

--

專案架構擴大、內容增多,時不時又有新添內容的需求,只靠單一 Seeds.rb 檔,會非常混亂;跟著這篇教程,一起實現:「執行的指定檔案,生成數據」,有條有理管理數據生成的相關檔案、讓 Seeds.rb 檔案內容不再失控。


Step 1 客製一個 Rake 指令(Rake Task)

在終端機執行:$ touch lib/tasks/split_seed.rake,產生一個 .rake 檔案;我們需要這個檔案來客製一個任務(Rake Task)。建立檔案後,在 lib/tasks/split_seed.rake 加入下方的代碼內容。

  • lib/tasks/split_seed.rake
# --=== 客製任務(Task):rake db:seed:single ===-- #

namespace :db do
  namespace :seed do
    task :single => :environment do

      # 透過路徑找到檔案

      filename = Dir[File.join(Rails.root, 'db', 'seeds', "#{ENV['SEED']}.rb")][0]

      puts "檔案:#{filename},開始執行。"

      # 如果檔案存在,執行檔案內容

      load(filename) if File.exist?(filename)

      puts "檔案:#{filename},執行成功。"
    end
  end
end


Step 2 創建 db/seeds 資料夾

在終端機執行:$ mkdir db/seeds,在 db 目錄下創建一個名為 seeds 的資料夾,用來放置 .rb 檔案。

作到這一步,環境就算設置妥檔了!未來你只要:

  • $ touch db/seeds/example_seeds.rb,新增 .rb 檔案。

    例如:我們創一個用來創建產品的 product_seeds.rb,並加入一些內容。

  • 運行指令

    • Localhost 本機端:$ rake db:seed:single SEED=example_seeds
    • Heroku 正式端:$ heroku run rake db:seed:single SEED=example_seeds

    假如我們要使用剛剛建立的 product_seeds.rb 生成產品數據,就在終端機輸入:$ rake db:seed:single SEED=product_seeds


成功!往後就可以利用這個方式,執行指定的 .rb 檔案、新增數據囉。




有任何開發上的問題,都可以透過 Slack:xbearx1987、anndo-2 找到吉米或我,我們很樂意為你解答。

如果你覺得教程對你有幫助,希望你能至我們的作品 J & A SELECT投下寶貴的一票!你的投票,代表的是對好作品、好教程的支持與鼓勵,也會成為我們持續分享的動力。

【JA魔改秘笈】十分鐘搞定商品列表、商品詳情頁面!

關於這篇教程

無論是上一次的 Job Listing 大賽,還是這一次的 JD Store 比賽,「作品醜」相信是不少同學特別糾結的地方,甚至成為了很多人作品難產的原因之一。吉米跟我準備了購物網站幾個主要頁面的板塊,希望能幫助大家脫離前端大坑。有了這樣一個雛形以後,你會有更多信心和時間進行後續迭代!

先前吉米為大家準備了 Landing Page 的部分:<【JA魔改秘笈】还卡在前端的坑吗?教你如何第一次做Landing Page就上手!!>;照顧完購物網站的門面,我們接著看看購物網站的「商品列表」、「商品資訊」這兩大主要頁面吧!

GitHub 開源代碼

專案連結:Jdstore-theme-simple

Demo

利用代碼,你可以快速裝修購物網站的「商品列表(products#index)」以及「商品資訊頁(products#show)」,輕鬆作出簡單、大方的樣式。

  • 商品列表(products#index)

  • 商品資訊頁(products#show)




GEM / 檔案路徑 / 功能與板塊

Gem

  • bootstrap-sass (*Bootstrap 模版)
  • font-awesome-rails (*Font awesome 圖標)

HTML + SCSS

功能 / 板塊

  • 商品列表 - 廣告圖
  • 商品列表 - 商品類型 & 品牌選單
  • 商品列表 - 頁面路徑 & 排序
  • 商品列表
  • 商品資訊 - 廣告圖
  • 商品資訊 - 商品類型 & 品牌選單
  • 商品資訊 - 頁面路徑 & 排序
  • 商品資訊 - 頁面左側:商品圖片
  • 商品資訊 - 頁面右側:商品主要資訊及功能




如何使用

Step 1. 鎖定想要用的板塊

Step 2. HTML 代碼

  • 到 app/views/products 中找到你要參考的頁面的文檔:
    • app/views/products/index.html.erb (*商品列表)
    • app/views/products/show.html.erb (*商品資訊)
  • 每一個大區塊都是以 <section> </section> 包住;板塊中的元件則使用 <div> </div> 來區隔。
  • 記住這個 Class 的名稱。

Step 3. CSS 代碼

  • app/assets/stylesheets/application.scss,利用快捷鍵 command + F 搜尋剛剛記下的 Class 名稱。裡面會包含該區塊使用到的 CSS 代碼。

這樣就大功告成,就是這麼簡單!接下來你就可以:

  • 替換圖片、連結。
  • 我們提供的代碼已經預先將很多元件以 <div> </div> 區隔並設置 Class(例如上圖的:.title.price),你可以針對你的喜好、需求,找到該 Class,調整前端細節(顏色、大小、間隔)。




過程中遇到任何問題,都可以透過 Slack:xbearx1987、anndo-2 找到吉米或我,我們很樂意為你解答。如果你覺得我們的前端模板對你有幫助,希望你能至我們的作品 J & A SELECT投下寶貴的一票!你的支持會成為我們持續分享的動力。

[直播筆記] 刻意練習(主講人:Xdite)

直播資訊

主講人:Xdite老師
時間:6月1日
時長:本次直播總時長預計30分鐘。
概要:

  • 刻意練習
  • JD Store 大賽最後如何衝刺
  • 如何做階段性複盤

直播筆紀

前言

  • 教大家擺脫「明明可以,卻沒去作,看著有實踐的人的車尾燈。」這樣的人生情境。

  • 常人最常犯的錯誤:以為自己落後,就不去作了。

  • 再次強調,魔改大賽的目的:「有一個完整的作品」;有一個作品,代表你有「克服障礙」的能力。(e.g. ihower 大神當年錄取 Xdite 老師,看的不是能力,而是因為 Xdite 老師有一個完整的作品 VeryXD 2.0。)


刻意練習(Practice)

  • 比賽拿名次,代表「綜合能力」越高;藉由挑戰比賽,來檢視自己的實力。
  • 大多數人的「刻意練習」其實只是「學習」(貼教材代碼、照著打),但 Xdite 老師對於「刻意練習」的定義:作一個又一個「完整的作品」;作一個完整的作品,才算一次練習。
  • 挑自己不熟悉的技能,作刻意練習。雖然過程不舒適,但會學會控制流程、找資源、協作,還能收穫巨大的回報(正面迴響、名氣、工作機會等等)。
  • 寫完整的文章,也算是一種「完整作品」;同樣能為個人帶來機會和好處。
  • 一直練、一直練、一直練。
  • 目前大家缺的是一股「狠勁」,而不是缺少能力。
  • Xdite 老師最初作 Landing Page 花上 30 天的時間,但經過練習,作了將近 30 個,現在只需要 30 分鐘就能完成一個 Landing Page。大家看到的「天才」表象只是結果。
  • 很多人會批判 Xdite 老師一直追求「極速」、「速成」,但事實上,不是追求捷徑,那些只是大量練習後的成果。
  • 刻意練習、讓自己有辦法迅速作出作品,讓自己達到登峰造極的境界。
  • 對自己「狠」!
  • 行動快、狠,才能變成人上人。只要肯跨出一步,你就贏過 80% 的人。


Q&A 時間

  • Q:感覺自己進入「新手撞牆期」,如何踏出舒適區?
    A:真實世界是 TM 沒有舒適區的,隨時都是 Hardcore 模式,要有一個心理認知:「所有事情都是難的,但我要想辦法克服。」。這個世界很難,但只要你有辦法完成,一定有人在前面等你、稱讚你。一開始沒有舒適區,但終點一定會有舒適區。沒有「舒適區」這種事,隨時都是「艱難區」,如果你一直有「舒適區」這種概念,你會進步得非常慢。

  • Q:卡關時,該如何面對挫敗感?
    A:蠢問題,這就是人生!

  • Q:接觸「未知」、「半未知」時,要如何提高成功率?
    A:開一個筆記本(紙本或空白頁面),把 StackOverflow 找到的答案作筆記,用關鍵字兜出樣貌、作出一個小功能。作完之後再重新騰一次,梳理出一個完整的 Solution。長期累積一個又一個的小套路,未來就有辦法直衝終點。

  • Q:怎麼樣作出面試時能說服面試官的功能?
    A:重點不是功能,而是讓自己變得有說服力,變成狼!要怎麼樣有「自信心」?TM 多練幾遍就會有自信心啦!不然你就算作出再強大的功能,面試時沒有這份自信,答得支支唔唔也是沒用。

  • 有效的進步,就是比上一次自己作的速度,快上一倍。

  • 編程就是先「抄」再說,貼 code、打 code,再自己作一遍。作了再說!不要妄想自己看了一遍大師的武功秘笈就能自己編一套武功出來。

【JA魔改秘笈】實作「用戶中心」 & 訂單欄位自動填入用戶資料

關於這篇教程

這篇教程介紹如何實現簡單的「用戶中心」,供使用者修改個人資料,以及如何在用戶創建訂單時,自動幫他填入資料。這樣的小小優化,可以讓作品更加逼近真實網站的體驗,作法相當簡單,來試試吧!


Part 1 新增 User 欄位:姓名、地址。

訂單中用到「姓名」、「地址」這兩項資訊,所以我們先來幫 User 這個 Model 添加欄位。


[Step 1]

終端機執行:$ rails g migration add_columns_to_user。執行後 db/migrate 的目錄下,會產生一個:「(一串數字)_add_columns_to_user.rb」的檔案。參考以下代碼修改檔案內容,並存檔。

  • db/migrate/(一串數字)_add_columns_to_user.rb
db/migrate/(一串數字)\_add\_columns\_to\_user.rb
class AddColumnsToUser < ActiveRecord::Migration[5.0]
  def change
    add_column :users, :name, :string  # 添加姓名欄位

    add_column :users, :address, :string # 添加地址欄位

  end
end

[Step 2]

存檔後,回到終端機執行:$ rake db:migrate


Part 2 建立「用戶中心」,讓用戶自行修改個人資訊。

我們還會需要一個「用戶中心」,讓用戶可以填寫「姓名」、「地址」。


[Step 1]

先來安置路徑。由於「用戶中心」算是 account 的相關頁面,我們新增一行 resources :users,放在 namespace :account 的區塊。

  • config/routes.rb
  namespace :account do
    resources :users # 加入這一行,新增「用戶中心」的相關路徑

    resources :orders
  end

[Step 2]

有了路徑後,我們還需要相對應的 Controller 來定義操作。在終端機執行:$ rails g controller account::users,產生 account/users_controller.rb。

  • app/controllers/account/users_controller.rb
class Account::UsersController < ApplicationController
  # 必須登入

  before_action :authenticate_user!

  # 編輯當前用戶資料

  def edit
    @user = current_user
  end

  def update
    @user = current_user
    @user.update(user_params)
    if @user.save
      redirect_to edit_account_user_path(current_user)
      flash[:notice] = '用戶資料更新成功'
    else
      render :edit
    end
  end

private

  def user_params
    params.require(:user).permit(:name, :address)
  end

end

[Step 3]

先在下拉式選單加上一個「用戶中心」的連結,讓用戶可以透過選單,進到「用戶中心」的頁面。

  • app/views/common/_navbar.html.erb
<!-- 前略 -->

        <!-- 用戶中心連結 -->
        <li><%= link_to("用戶中心", edit_account_user_path(current_user)) %></li>
        
        <li><%= link_to("個人訂單列表", account_orders_path ) %></li>
        <li><%= link_to(content_tag(:i, '登出', class: 'fa fa-sign-out'), destroy_user_session_path, method: :delete) %></li>

<!-- 後略 -->

[Step 4]

終端機執行:$ touch app/views/account/users/edit.html.erb,建立「用戶中心」的頁面。

  • app/views/account/users/edit.html.erb
<%= simple_form_for [:account, @user] do |f| %>

    <%= f.input :name, :label => '姓名' %>
    <%= f.input :address, :label => '地址'  %>
    <%= f.button :submit, '更新', class: 'button' %>

<% end %>

完成上述 Step 1 ~ Step 4 的操作後,用戶就可以透過下拉式選單進入「用戶中心」,並且對個人資料進行修改。

  • 功能演示


Part 3 修改訂單表格,自動填入使用者資料。

最後,我們要改造 checkout.html.erb,讓表單讀取用戶資料。我們還可以再作一些小修改,讓表單更符合真實網站的體驗。


  • app/views/carts/checkout.html.erb
  <div class='order-form'>

      <%= simple_form_for @order do |f| %>

        <legend>訂購人</legend>

        <div class='form-group col-lg-6'>
            <%= f.input :billing_name, placeholder: '請輸入訂購人姓名', input_html: {value: current_user.name}, :label => '姓名'  %>
        </div>
        <div class='form-group col-lg-6'>
            <%= f.input :billing_address, placeholder: '請輸入訂購人帳單地址', input_html: {value: current_user.address}, :label => '地址'  %>
        </div>
        <!-- 收貨人欄位:姓名、地址 -->
        <legend>收貨人</legend>

        <div class='form-group col-lg-6'>
            <%= f.input :shipping_name, placeholder: '請輸入收貨人姓名', input_html: {value: current_user.name}, :label => '姓名'  %>
        </div>
        <div class='form-group col-lg-6'>
            <%= f.input :shipping_address, placeholder: '請輸入收貨人收件地址', input_html: {value: current_user.address}, :label => '地址'  %>
        </div>
        <div class='checkout'>
          <%= f.submit '生成訂單', class: 'btn btn-lg btn-danger pull-right', data: { disable_with: 'Submitting...' } %>
        </div>

      <% end %>
  </div>


像這樣的一段代碼,看似冗長、複雜,但別慌,這裡一一說給你聽!

<%= f.input :shipping_address, placeholder: '請輸入收貨人收件地址', input_html: {value: current_user.address}, :label => '地址'  %>`

像這樣一行代碼,可以拆分細看:

  • placeholder: '請輸入收貨人收件地址':欄位中的提示文字。
  • input_html: {value: current_user.address}:設定要代入的值(value),這裡的範例是將「當前用戶的地址(current_user.address)」的值填入欄位。
  • :label => '地址':命名欄位的標題。


Simple_form 還有一些可以探索的進階用法,像是利用 input_html: { class: 'CSS樣式'} 修改欄位樣式等等,這篇教程就不贅述了,有興趣的同學,歡迎移駕至我的搭擋 Jimmy Wang 的嘔心瀝血之作:

< Simple_form 進階用法:優化欄位設置(包含Model设定)>


  • 功能演示

大功告成!


  • 實際運用在作品中可以達到以下效果:




如果覺得這篇教程有幫助,歡迎至:J&A SELECT 的作品頁面 點下「支持TA」。你的寶貴一票,對我們是很大鼓勵和支持,也是我們持續分享的動力!:)

[直播筆記] 如何長期維持超人一般的高效模式?(Xdite 老師的 Q&A 時間)

今天直播時間,看 Q&A 沒有什麼人提問,就斗膽問了老師兩個問題,得到誠意滿滿的回答!

「想知道老師是怎麼長期維持超人一般的高效模式?」

所謂的「高效」,其實是「高速度」跟「高效率」,將兩者分開來談。

  • 高速度
    高速的關鍵是「激情」,你如果對你目前在作的事情有「激情」,自然會加速去執行。

  • 高效率
    唯有不斷練習,達到「熟練」,才能促成高效率。反覆練習,找到一件事情的套路,練到「不加思索便能出手」的境界。達到這樣的程度後,高速、高效完成任務,自己會有滿滿的成就感,形成一個正循環。


「感覺老師好像不太會陷入發懶或是無動力的狀態,這其中是不是有秘訣?」

如果發懶了,切換模式,作其它「對成長有助益」的事情。人會懶、沒動力,通常原因是出在「膩了」,這種時候就去玩點新東西。像是可以跟隊友提議交換任務,像是:作後端膩了,就自告奮勇去改前端,保證會非常刺激。

大多狀態其實都源自於「情緒」。強者之所以是強者,是因為他們已經察覺自己身上的「開關」,並熟知如何開啟、關閉。

老師舉他自己的例子:

  • 狀態:用手寫,進入專注模式。
  • 閱讀:利用 16 格筆記。
  • 寫作:利用 9 格筆記。
  • 面對道德綁架:避開,閃得遠遠的。

持續練習「認清問題的癥結點 → 找到解決方法」,久了自然就能內化、掌握開關。


「如果自己或是隊友不在狀態上,要如何自救跟救人呢?」

要知道自己遇到的是什麼問題,誠實跟隊友說自己狀態不好,直接溝通、找到折衷方案,保持一個最小、可以前進的狀態。協作之間最重要的是「透明」;最怕的是:隱瞞、說謊,自己不處理自己的狀態,或是對方選擇視而不見、悶在心裡,只要雙方之間「不透明」,鴻溝會越來越深、協作關係陷入僵局。要幫助隊友的話,要營造一個安全的環境,讓對方可以放心說出來。

JD Store 魔改大賽作品介紹:J&A SELECT(5/27 更新)

大家好,J&A SELECT 是由 Jimmy 王品睿與 Anndo 柯禹安 兩人遠端協作的選物網站,提供「日常文具」、「生活器具」、「個人單品」三大類型的高質量單品,為你呈現美好的生活品味。


這篇文章涵蓋詳細的作品細節:

  • 頁面 / 功能介紹
  • 版本紀錄
  • J & A 魔改秘笈
  • Models
  • Gems


如果你喜歡我們的作品:J&A SELECT,或覺得我們的文章對你有幫助,歡迎前往我們的參賽頁面投下你寶貴的一票!你的支持,會是我們持續分享的動力。



頁面 / 功能介紹

首頁

以 Landing Page 的概念製作首頁,首頁提供了主要幾項資訊:「品牌故事」、「商品主要類型」、「精選商品」、「嚴選品牌」。

  • 首頁廣告圖片自動輪播。

  • 用戶可切換、瀏覽多張首頁廣告圖片。

  • 用戶可點擊「商品主要類型」,前往商品列表瀏覽該類型的所有商品。

  • 用戶可點擊「精選商品」,前往特定商品的資訊頁面。


商品列表

商品列表,依照商品建立時間顯示上架商品。商品列表有幾個主要功能:「篩選」、「排序」、「所在頁面路徑顯示」

  • 用戶透過選單,選擇「分類篩選」或「品牌篩選」,顯示符合條件的商品。
  • 顯示「所在頁面路徑:J&A SELECT / 類型 / 分類 / 商品名稱」,用戶可透過路徑跳轉至特定的篩選頁面。例如:「J & A SELECT / 個人單品 / 皮件 / Il Bussetto 拉鍊式 皮革皮夾」,點擊「皮件」,即可跳轉至該分類篩選的頁面。


商品資訊

除了商品的幾項主要資訊(名稱、價錢、敘述、品牌、庫存),商品資訊頁可進行以下操作:「切換幣值」、「加入 / 取消收藏」、「加入購物車」。

  • 用戶可透過「切換幣值」選單,將商品金額(新台幣 NT$)轉換為特定幣別(人民幣 / 新台幣 / 歐元 / 美金 / 日圓)及匯率換算後的價格。
  • 用戶可選擇商品數量,直接加入購物車。商品數量不得大於庫存。
  • 「切換幣值」、「數量」等更動,不會刷新頁面。
  • 用戶可點擊「加入收藏」,將商品納入「願望清單」。
  • 用戶可點擊「加入購物車」,將商品放入「購物車」。

願望清單

顯示用戶收藏的所有商品,用戶可對願望清單上的商品進行操作。

  • 用戶可透過「移動至購物車」,將商品從願望清單移至購物車。
  • 用戶可將商品從願望清單中移除。

  • 用戶的願望清單沒有內容時,會顯示 3 樣「推薦商品」。

購物車

顯示用戶加入購物車的所有商品,用戶可對購物車內的商品進行操作。

  • 用戶可清空購物車。
  • 用戶可將商品從購物車中移除。
  • 用戶如果有切換幣值,購物車會以該幣值計價。
  • 用戶可在購物車頁面調整商品數量。商品數量不得大於庫存。

  • 用戶的購物車沒有內容時,會顯示 3 樣「推薦商品」。

訂單生成

用戶如果有在「我的帳戶」設定:「姓名」、「電話」、「住址」等資料,訂單資訊表格會自動填入用戶的資料。

我的帳戶

用戶可對「用戶名稱」、「性別」、「生日」、「電話」以及「住址」進行修改。

我的訂單

用戶可以瀏覽過去下訂的訂單。

  • 訂單明細顯示商品圖片。
  • 用戶可點擊商品標題,連結至商品資訊頁。如果該商品已下架,則顯示下架資訊。



J&A 魔改秘笈

協作


前端效果 / 後端功能實現




版本紀錄

2017-05-25 — J&A SELECT v1.1.5

  • Footer 樣式改版。
  • 新增「推薦商品」功能,用戶的願望清單、購物車,在空空如也的情況下,會看到推薦商品。
  • 優化商品資訊頁 URL,顯示 ID 及商品名稱。


2017-05-25 — J&A SELECT v1.1

  • 「我的訂單」中,訂單顯示商品圖片,並可連結至商品資訊頁。(如果該商品已下架,則顯示下架狀態。)
  • 購物流程體驗優化:

    • 用戶在商品資訊頁,可決定購買數量(不能超過現有庫存),直接加至購物車。
    • 「切換幣值」、「數量」等更動,不會刷新頁面。
    • 購物車中的商品,可調整商品數量(不能超過現有庫存)。
    • 儲存用戶選擇的「幣值」,購物車、訂單均以該幣值計價。
    • 訂單欄位自動填入用戶資料(用戶於「我的帳戶」中的設定)。


2017-05-21 — J&A SELECT v1.0

一般用戶 + 管理員

  • 瀏覽首頁
  • 註冊帳號 / 帳號登入 / 修改用戶資訊
  • 搜索功能
  • 篩選功能
  • 購物功能(加入購物車、結帳、生成訂單)
  • 加入願望清單功能
  • 客服功能
  • 簡體中文 / 繁體中文切換功能

管理員

  • 後台專區進入權限
    • 商品管理
    • 品牌管理
    • 類型 / 分類管理
    • 訂單管理
    • 首頁廣告管理




Models

  • User 用戶

    • name 用戶姓名
    • nickname 暱稱
    • address 地址
    • phone 手機
    • birthday 生日
    • gender 性別
    • is_admin 管理員權限
  • Products 商品

    • name 商品名稱
    • description 商品敘述
    • price 商品售價
    • quantity 庫存數量
    • category_id 商品所屬的分類ID
    • brand_id 商品所屬品牌ID
    • is_hidden 商品隱藏狀態
  • Product_image 商品圖片

    • product_id 圖片所屬的商品ID
    • image 圖片
    • main_image 商品首圖有無
  • Brands 品牌

    • name 品牌名稱
    • description 品牌敘述
    • logo 品牌標誌
    • is_hidden 品牌隱藏狀態
  • Category_group 主要類型

    • name 類型名稱
    • description 類型敘述
    • logo 類型封面圖
    • is_hidden 類型隱藏狀態
  • Categories 分類

    • name 分類名稱
    • description 分類敘述
    • logo 分類封面圖
    • category_group_id 分類所屬的類型ID
    • is_hidden 分類隱藏狀態
  • Cart 購物車

  • Cart_item 購物車品項

    • cart_id 品項所屬的購物車ID
    • product_id 品項的商品ID
    • quantity 商品數量
  • Order 訂單

    • user_id 訂單所屬的用戶ID
    • billing_name 聯絡人姓名
    • billing_address 聯絡人地址
    • shipping_name 收件人姓名
    • shipping_address 收件人地址
    • shipping_phone 收件人電話
    • total 總金額
    • is_paid 付款狀態
    • paymen_method 付款方式
    • token 亂數生成
    • aasm_state 訂單狀態
  • Order_item 訂單品項

    • order_id 品項所屬的訂單ID
    • product_name 商品名稱
    • product_price 商品金額
    • quantity 商品數量
    • product_id 商品ID(5/23 新增)
  • Intro 廣告圖

    • title 標題
    • content 文案內容
    • image 圖片
    • link 廣告連結
    • is_hidden 廣告隱藏狀態
  • Wish_list 願望清單

    • user_id 願望清單所屬的用戶ID
    • product_id 願望清單內的商品ID
  • Currency 幣別

    • symbol 幣別符號
    • name 幣別名稱
    • rate 匯率
  • Color 商品顏色(5/26 新增)

    • name 顏色名稱
    • code Hex 色碼




Gems

  • 帳號系統

    • devise
  • 前端視覺

    • bootstrap-sass
    • simple_form
    • will_paginate
    • will_paginate-bootstrap
    • font-awesome-rails
    • masonry-rails
  • 搜尋功能

    • ransack
  • 圖片功能

    • carrierwave
    • mini_magick
  • 訂單狀態

    • aasm
  • AWS 雲端儲存

    • fog-aws
    • figaro
  • Intercom 客服系統

    • intercom-rails

[筆記生肉] 教你如何使用 User Story、Tower 、 Github 進行協作開發(主講人:ihower)

直播資訊

主講人:ihower 老師

時間:5月18日 週四 20:00

時長:本次直播總時長預計30分鐘。

概要:ihower 教你如何使用 User Story、Tower 、 Github 進行協作開發。

直播筆紀

什麼是User Story

  • 使用「用戶的觀點」進行功能的描述

撰寫的秘訣

一、粒度大小很重要(要描述多大、多小的事情)

  • 舉例來說,對投資人可能用大一點的項目描述,但如果是技術團隊之間,則用較小的描述大小。
  • 拆分故事不用技術來切分,「對用戶有價值的功能」才是我們要描述的。
  • CRUD(5 個欄位),不用分開寫成 20 條 User Story。
  • 不要用零件去切,以「對用戶有價值的功能」去演進;例如:滑板 → 滑板車 → 腳踏車 → 機車 → 汽車,演化過程中每一個型態都是用戶可以使用的。

二、可以徹底完成的小故事

  • 避免籠統的描述方法。例如:「管理員可以管理產品」就太籠統了,怎麼樣叫做「管理」?應該要拆分為「管理員可以上架商品」、「管理員可以上傳多張圖片」等等。

三、描述功能需求,而不是解決方案

  • User Story 是要讓非開發人員也能看得懂,所以不需要技術規格相關的描述,像是:UI 規格、開發語言及框架。

四、辨識用戶角色

  • 角色是誰?角色可以作到些什麼事情?
  • 使用「主動語態」:「商品可以被用戶瀏覽」(X);「用戶可以瀏覽商品」(O)。
  • 用戶角色越多種,複雜度就越高。為了 MVP(Minimum Viable Product 最小可行性產品),建議將角色數量控制在兩種就好。

收集、排序多條 User Stories

X 軸:照時間分,由左至右。
Y 軸:照優先順序,由上至下。

User Stories 有兩種排序方式:「Bottom-up」、「Top-down」:

  • Bottom-up 排序法

    • 寫 10 - 20 條,照時間順序由左到右排序,並把類似目的的功能歸類在一起(例如:跟「結帳」流程有關的放一起)。
    • 接著,總結出主要活動,每一個分類都是一種角色為主。除非是有互動的情況(例如:客服系統,用戶會與管理員互動),才會歸在同一個分類。
  • Top-down 排序法

    • 列舉出主要的活動。
    • 每個活動拆分 3 條以上的用戶故事。
    • 調整優先度,由上「高優先」至下「低優先」。這樣就可以劃分出第一版 Must Have、第二版 Should Have、第三版 Could Have 三階段的項目。

如何使用 Tower

Tower:免費的線上項目管理軟件。

  • 註冊後,新建「看板項目」。
  • 定義項目流程,通常是「To-do」、「Developing」、「Done」三個主要欄位。也可以加其他欄位像是:「需求」、「第一版」等等。
  • 每一條 User Story 可以在施工階段,利用「添加檢查項」加入該 User Story 的開發細項。像是建立 Controllers、Views、Model 等等。

如何用 GitHub 進行協作開發

為什麼要使用 Git & GitHub?

  • 共享代碼。
  • 避免修改代碼時,覆蓋隊友的代碼。
  • 不幸改到同一個地方時,可以解決衝突。
  • 記錄誰改的?為什麼?
  • 版本控制,分為「穩定版本」和「開發版本」。

示範情境:Rejected,同時修改不同檔案。

  • 衝突狀況:兩人同時,A 修改後先推上去。這時候,B 在未更新專案的情況下,再將修改推上去,會遇到 rejected 的錯誤訊息。

  • 解決方式:這種時候 B 要 $ git pull 將 A 的版本拉下來,進行「自動合併」,再重新 push。

示範情境:Conflict,同時修改同一個檔案。

  • 衝突狀況:兩人同時改同一個檔案、同一段代碼,A 修改後先推上去。B 在未更新專案的情況下,執行 git push 時,同樣會遇到 rejected 的錯誤訊息。但與上一個情境不同的是,B 用 $ git pull 將最新進度拉下來時,會遇到「自動合併失敗」(Automatic merging failed);「自動合併」不是無所不能,同一個檔案的衝突狀況必須要靠手動排除。
  • 解決方式:承上,如果 B 執行 $ git status 檢視現況,會看到該檔案顯示為 both modified。打開檔案修改,決定要最後留下的版本並進行 commit,再重新推上專案即可。


示範情境:進階用法

利用 $ git checkout -b < branch 名稱 >從 Master 切出新的分支,作功能開發,完成後上傳。回到 GitHub,點擊 New pull request,通知主程式(或團隊成員)有上傳新的分支。主程式(或團隊成員)會收到 email 通知,如果確認沒有問題,可以執行 Merge pull request 將分支合併回主幹。

其他補充

SourceTree:Git 視覺化工具

  • 設定 iTerm 終端機指令,利用 $ stree 開啟 SourceTree(請先下載 SourceTree 軟件,並放置於「應用程式」資料夾中)。

    • iTerm 終端機輸入 $ atom ~/.zshrc,用 Atom 開啟 zshrc 檔進行修改。

    • 在文件尾端加入一行:alias stree='/Applications/SourceTree.app/Contents/Resources/stree'

    • command + Q 關閉 iTerms,重新開啟後,輸入 $ stree 看看能否正常開啟。
  • 除了我們習慣的終端機指令 $ git add$ git commit,我們也可以利用 SourceTree 對修改進行 commit。

程序員素養

  • 培養好習慣,不是所有檔案都要 commit!例如執行 $ rails g scaffold 會產生許多用不到的空檔案,判斷後,把不需要的檔案刪掉,再進行 commit。

其他觀察

  • 在終端機中,利用 $ vi <檔案名稱>,可以在終端機直接修改檔案。

ihower 推薦閱讀

[筆記生肉] 商店開發實戰技巧(主講人:Nic)

直播資訊

主講人:Nic 老師

時間:5月15日 週一 20:00

時長:本次直播總時長預計30分鐘。

概要:Nic 老師在這次直播會教你用神器 Debug ,同時也會講解購物車相關的設計內容,讓你透過這次直播能夠更明白這些開發技巧及細節。

直播筆紀

心態提醒

  • 「記住原點,比賽是為了自己。」你有沒有成長,才是最重要的。不要一直跟別人比較,不用因為其他人的表現而左右自己的學習!
  • 團隊協作,一起成長。


如何 Debug

Gem 神器推薦:

gem 'pry' #執行時的攔截呼叫

gem 'awesome_rails_console' #高顏值金手指介面(美化 Rails Console 的排版)

建議裝在 development 下;如果沒有區分,直接推上正式端,會有可能拖慢網速。裝法請參考:

  • Gemfile
group :development, :test do
  gem 'pry'
  gem 'awesome_rails_console' 
end


購物車開發技巧

  • pry 的利用方式

    • 利用 binding.pry 下斷點(如果要在 .html.erb 下斷點,用 <% %>binding pry 包起來即可,也就是 <% binding.pry %>。 );Ruby 是腳本式語言,會由上至下一行行執行,所以一遇到斷點 binding pry,程序就會停下來。
    • 停在斷點後,至 Rails Console 查詢。
      • 輸入參數,查詢值。
      • .class:查詢值的型態
      • .to_i:將值的型態轉換成 integer
    • 要離開 Rails Console 輸入 $ exit 離開。
  • ||=:「或等於」(白話文:如果沒有的話,就給;有的話就不給。)

  • session 與 cookie:請善用 Google 大神,過去學員已經留下很多的參考資料跟說明。

  • 搜尋資料常用:

    • find:找 id; 例如:User.find(2),找 id 為 2 的 User。
    • find_by:找某一筆; 例如:User.find_by(email: 'admin@test.com'),會找到 email 相符合的資料。
    • where:找多筆,針對數據庫下指令撈資料; 例如:Product.where(price: 2800),找到符合「價格為 2800」的產品。或是利用 Product.where(price: 1..5000), 找介在「價格區間」的產品。
  • 兩種常見符號:!?

    • !:「不等於 / 否」,也可以使用 unlessif !current_user(假如是「非用戶」) 跟 unless current_user(除非是「用戶」)是同樣意思。
    • ?:通常回傳 true / false; 例如 @user.is_admin?
  • Seed.rd 檔

    • 利用圖片地址,寫成 open("圖片地址")
    • 詳細代碼:Nic 老師 GitHub 上的 commit
  • Nic 老師手把手帶你作「後台調整產品順序功能」

    • 安裝 Gem:gem 'acts_as_list'
    • 學習閱讀開發者的說明文檔,照著步驟執行。
    • 詳細代碼:Nic 老師 GitHub 上的 commit

[CSS] text-decoration 性質

text-decoration 作什麼用?

實作「購物車清單」時,我們在 app/views/carts/index.html.erb 中有以下代碼:

<div class="row">
  <div class="col-md-12">
    <%= link_to("清空購物車", clean_carts_path ,
     method: :delete , class: "pull-right",
     style: "text-decoration: underline;",
     data: { confirm: "你確定要清空整個購物車嗎?"} )%>
    
<!-- 下略 -->


CSS 中 text-decoration 這個性質(property),顧名思義,就是讓我們為文字作裝飾;裝飾像是:增加底線、刪除線、上線。利用 text-decoration:文字特效參數,我們可以達到以下效果:

[HTML] <td> 的 colspan 屬性

<th colspan="2"> 是什麼意思?

實作「購物車清單」時,我們在 app/views/carts/index.html.erb 中有以下代碼:

<table class="table table-bordered">
  <thead>
    <tr>
      <th colspan="2">商品資訊</th>
      <th>單價</th>
      <th>數量</th>
    </tr>
  </thead>

<!-- 下略 -->



HTML <td> 標籤的 colspan 屬性,可以讓表格的欄位(td)橫跨多欄(columns);類似我們在 Microsoft Office 等文書軟體中常使用到的「合併欄位」功能。

<td colspan="number">



運用 <td colspan="number"> 可以讓表格的欄位達到以下效果:

[筆記生肉] 敏捷項目管理(主講:Xdite)

項目開發會遇到的難題

  • 真實網站非常多 User Story
  • 非常多要素相互配合
  • 複雜、難掌握

怎麼樣贏 Hackthon?

  • 關鍵:「投影片夠牛逼、完美的 Pitch 技巧。」; 代碼不用完美、點子不一定要最好,最後 Demo 的樣貌才是關鍵。
  • 不想當 Ptt 黨的折衷作法: 投影片最優先、點子好、代碼還 OK。

Hackthon 與真實世界的項目是非常相似的

Hackthon 產品
牛逼投影片 牛逼投影片
正確的產品、適合官方發佈 被市場認可並獲利
最小可行性產品 在正確的時間點進入市場

  • 都是要用好的投影片、Demo 來說服創業投資人。
  • 產品必須要是 Minimum Viable Product(MVP),最好要是 Product Market Fit(適合市場、有辦法生存)。
  • 在對的時機出現在市場上。

時間管理概念

  • STEP 1. 估算:考慮到「莫非定律」,出錯機率往往是平常的 3 倍。只挑最核心的功能作。

  • STEP 2. 基礎部署:不要找太多隊友,人多口雜;只找一個隊友,簡單的討論、部署。選擇在初期部署(Deploy),是因為這個環節容易出問題,把最大的風險先抓出來解決。

  • STEP 3. 實作主要功能:搶在中午前實作主要功能,利用心理戰給競爭對手製造壓力。

  • STEP 4. 實作小功能:

    • 逐一填補細節
    • 真實用戶測試
    • 預防預期外事件
  • STEP 5. 完稿:

    • Landing Page 說明
    • 設計投影片
    • 反覆排演

其他 90% 的參賽者是如何搞砸 Hackthon 的?

  • 花太多時間找強者當隊友
  • 想法多且雜,無法取捨
  • 花太多時間卻只作出不完整的功能
  • 倉皇上線
  • 評審使用時馬上出 Bug

項目管理技巧

  • 大、中、小項目的管理原則其實都是相通的。利用大型專案的管理方式去應對像 Hackthon 這樣的小型項目。
  • 必須預留 1/3 的時間作測試,剩下的 2/3 才是作開發。

    如何分配 2/3 的開發時間:
    Part 1. 地面作業
    Part 2. 主幹功能
    Part 3. 細小功能
    如此一來就有充裕的時間打磨細節!

  • 面對大項目,不要慌張或以為埋頭苦幹就行,最重要的是「定義何謂『成功』」。(e.g. Hackthon 必須先透過優秀的 Demo,讓評審看見產品的價值,背後的代碼才有可能被看見。)

  • 「項目是活的」:很多預想跟當初的計畫會有出入,所以要明確定義「成功」,然後盡可能往這個目標逼近。

  • 儲存時間揮霍在「排練與測試」,而不是浪費時間在無意義的加班、失火 / 救火。

Xdite 老師總結重點

不要以為有了 Rails 的技能就無所不能。未來的挑戰很多,無論是作項目,還是說任何需要花時間的事情,是需要項目管理能力。

項目管理基礎篇心得 — 個人心得

這個項目管理的單元是在招聘網站魔改大賽最後一天(5/7)才看的,特別有感悟:

  • 沒有把握好大賽開始前的一週先完成一個作品的雛形,還在慢條斯理地練習教材,這個時間花費得很不經濟!系統一開放,只能用半成品「倉皇上線」。大賽初期的自己就是那 90% 搞砸 Hackthon 的人。
  • 前期不顧一切把作品推上線、有一個初版的作品頁面還是非常必要。一旦有了「緊迫性」,就能拋開「完美主義」這個包袱,逼著自己把主要功能和頁面生出一個最小可行版本。當時間有限,任務的優先順序也就格外明確了。

[分享] Job Listing 魔改大賽 — 調適心態、持續迭代

前言

從系統一開放慌慌忙忙將未完成品推上線,歷經多次迭代、讓作品進化到還算及格的樣貌,在大賽中後期很幸運獲得不少肯定。走過這麼一遭,想趁著進入新的學習階段前,挑選幾個自己在大賽期間經歷的坑和領悟,作一次複盤。

容我引用李小旋同學一段成熟且有智慧的話:「其實我們每次雖然作不同的事情,但是情緒其實是類似的。『不自信、迷茫、害怕、焦慮』。慢慢調,每一次調整,下一次就會調整得更快。」接下來的學習、商店大賽,我們也許又會再一次跌入同樣的深坑。我們無法控制情緒,但只要一次又一次的調適,日後再被絆倒,至少就知道該往什麼方向擺正心態了。希望這篇魔改大賽復盤分享文,能對同學們起一些幫助。

如果你對我的開發、情緒坑歷程紀錄有興趣,歡迎參考下方的 < Job Listing 第二期魔改大賽 - 歷程紀錄 > 連結。另外也再次附上 Xdite 老師和 Nic 助教兩位雞血補師這幾次直播的筆記,每當我身陷情緒深坑,除了向外求援,都是靠著回顧筆記,矯正自己的學習心態與姿態(Xdite 老師的語錄有如當頭棒喝!)。

Anndo 的魔改大賽歷程紀錄:

Xdite 老師的雞血直播筆記:

Nic 助教的技術向直播:

初期心態建立 — 「不關注得票,只在乎自身的成長。」

Xdite 老師其實早在大賽開始之前,就在直播中耳提面命:

  • 「用大賽驗收學習成果。不要怕會『輸』或是作出來的東西『醜』;參加大賽是為了調動目前所學的技能、逼出潛能!比賽就是一個大寶箱,請『厚著臉皮參加』。」
  • 「參加魔改大賽的目的,不是與其他人競爭,而是讓自己有一個完成的作品。」


幾句話把魔改大賽的目的講得很明確:

  • 知識遷移:讓我們試著把前面幾課的基礎技能和知識,實際運用在真實項目上。
  • 逼出潛能:老師和助教給了你魚竿後,你能釣到小魚還是大魚?或是自己開外掛把魚竿升級?這都是取決於自己。利用大賽這個機會,把潛能一點一滴榨出來。
  • 自己完成一個完整的項目:如果要轉職當程序員,魔改作品可以是未來作品集的一部分;如果要作產品、創業,大賽就是給我們機會「讓點子落地」。


魔改大賽開放後,相信不少人也跟我一樣,一看到同學紛紛發表,還有完成度超高的強者作品,瞬間把這些道理拋諸腦後。當時匆匆忙忙,只顧著推上線,上線時 Landing Page 有一大塊甚至都還是 Nic 助教提供的模板樣式呢。也厚著臉皮把作品連結丟去微信群組求關注、抱著僥倖的心態想撈個幾票,但我一發完就後悔、羞愧極了:「現在作品是這付樣貌,我憑什麼期待別人投票給我或追蹤後續迭代?就算多了幾票,真能證明什麼嗎?」


冷靜想想,發現自己是一腳踩入笑來老師所說的人生三大坑之一:「心急火燎地隨大流。」。要知道,瞬間收穫眾多票的吉米同學可是花了很長一段時間精心雕磨自己的職贏網,機會本來就是留給準備好的人;在瞎湊熱鬧跟四處拜票前,我該作的是:「藉由自己的作品打理好,提高實力,升級學習心態和系統」,每日仍應該照表操課:作品迭代和 ORID 都不能少。


過多的「虛榮心」跟「競爭意識」只會讓腦袋無法正常運轉,思路不清晰的情況下成不了事。下了決心,除非是要上傳新迭代的作品截圖,不然在自己有端得上檯面的作品前,絕不去關注自己的票數。照羅胖所說的「不讓過去的經驗影響現在,也不讓未來的妄念影響當下,我只純粹關注當下的目標」,老老實實往眼前的目標「讓自己有一個完成的作品」努力。

學霸的存在不是為了碾壓你,是給你作最好的學習榜樣。

學霸也是靠「努力」才如此牛,要先反問自己:「我盡力了沒?」

一開始排名就在前面的同學,賽前早就煞費苦心在寫代碼了,這些「用心」在作品網站和 GitHub 上一覽無遺(網站功能的完整度和流暢體驗,原代碼大量的 commits、備註)。回想大賽開始前一週,自己還是以悠悠哉哉的步調在作練習,連「你哪有全力以赴,你只是盡力而為。」這句話中的「盡力而為」都談不上。


因此,與其用「因為他之前就是作程序員」、「因為他是全職在學習,有大把時間」、「他資質好、天賦高」這些方便的理由來解釋學霸的作品,不如認清自己跟學霸差就差在「勤奮」二字(就算真的有其他條件上的差異好了,這邊引用笑來老師一句,「難道起點比別人低,你就不成長了嗎?」),趕緊打開 Atom 跟終端機開始敲代碼,投入時間跟心力持續迭代吧!

把學霸當教材。並帶著明確的疑問和目標,到學霸的代碼裡撈答案。

曾經被優秀作品震撼、有過「不玩了。」的念頭的同學,你並不孤獨(相信二期學員在大賽開始 24 小時內,心情都特別糾結)。然而,換個角度想,一開始就有像這樣職贏網這樣一個完整度沒有 100% 也有 99% 的項目,對二期的我們來說有幾個好處:

  • 刺激群眾,讓二期魔改大賽的參賽作品的程度更上一個檔次。
  • 網站跟原始碼就亮在那,很多功能、排版、前端視覺都有仿效對象。


再回想一次 Xdite 老師的話:「參加魔改大賽的目的,不是與其他人競爭,而是讓自己有一個完成的作品。」。以「競爭」為出發點、把大家當「對手」,只要你一被震懾到,自然就想放棄了。如果我們是以進取型人格(Be-Better Type)的心態去思考,只關注自身的成長,並且想要讓自己的作品盡善盡美,有這樣的「模範」不正是賺到了嗎?


我在實作「收藏 / 取消收藏(star/unstar)」功能時,先回歸 Rails101 照著實作,完成後,帶著自己的疑問去吉米王的 GitHub 逛逛。看到他的代碼頓時恍然大悟!趕緊寫下筆記,心裡暗自感激。強烈推薦同學,帶著你的疑問,把強者的 GitHub 當參考書「解答本」翻翻吧,肯定會很大的收穫。


(太久沒寫字,字整個走樣了...字醜勿怪!)

開發心態 — 擺脫「完美主義」,先求有再求好的 60 分心態。

與其追求單一個區塊的 100 分,不如追求整體的 60 - 80 分。

我自己也經常會被「追求 100 分的完美主義」給絆倒。更糟糕的是,代碼寫到一半發現不順手或前端越改越醜,就會忍不住砍掉重來。聽了 Nic 老師的 git stash(把修改丟到暫存、清空)跟 git checkout(恢復到上一個 commit)的小訣竅後,這個傾向更嚴重,只要不合意就馬上推翻重來,因為太方便了。最後結果就是,幾個小時過去,進度可能都還是 0。


Xdite 老師在 < 女生學得會編程嗎?放下完美執著就學得會! > 一文中寫到:「男生會要求自己 60 分及格,就會繼續往前。而女生要是自己沒有 90 分,就會覺得很害怕。所以最後女性往往最後就容易放棄,然後直接重做。」現在回想起來,我就是這樣的狀況啊!


但在執著 100 分之前,再次回憶一下魔改大賽的目的:「完整的作品」。這樣一想,就會驚覺自己在特定區塊的執著有點傻;就算 Landing Page 真的雕至完美(但究竟何謂「完美」?),如果點進去工作列表,看到一個簡陋的頁面,網站的體驗也是大打折扣。先要求自己只作到 60 分就好,一步步往其他功能、頁面推進,隨著作品的樣貌逐漸成形,心裡就會更踏實、有動力優化。

你的「60分」也許在別人眼中並不差,甚至還蠻好的!

為了要讓切換語系功能趕快上線,中文版的文案內容是利用下班前半小時在 Slack Post 上擠出來,回家想也不想就貼上。

草草生出來的文案,自己看了心裡實在很彆扭。沒想到繁中、簡中版上線沒多久後,卻收到這次大賽最令我意外的讚美(還不只一個,也是醉了。):「文案寫得很好耶。」、「文案高手,很強。」、「文案寫得很詳盡!」。最後,這版文案就再也沒改過了...


所以想鼓勵同學,勇敢把作品、新版本推上線吧。在別人看到、給予任何反饋之前,先別忙著自我否定。這版不好,大不了再修正一版 70 分、80 分的優化版本。況且,你可能根本就不差,犯不著妄自菲薄!

設置停損點,大膽嘗試雖好,但也要學會果斷放棄。

開發(特別是前端)要設一個停損點,先求有再求好。當發現耗費太多時間還沒理出個結果,就先擱置吧;睡個一覺,或是先轉戰其他功能,再回頭寫寫看,也許會更有進展。

[工商服務區塊]

魔改大賽最後已經有點乏力了,無力再拉票,同學們隨意吧!也歡迎大家隨時來我的 Logdown 踩踩,留言或隨時微信交流。

[筆記生肉] 學一遍就能把知識焊入大腦的技法(主講:Xdite)

直播資訊

主講人:Xdite老師
時間:5月4日20:00
時長:本次直播總時長預計30分鐘。
概要:Xdite學一遍就能把知識焊入大腦的技法

直播筆紀

「如何學一遍就能促成永久記憶?」

  • 訣竅:「提取練習」,學到一件事就馬上(用手!)寫下要點並復述給別人聽。

  • 原理:

    • 不能只有「輸入」,這是一般人的通病。如果只有輸入,知識進了大腦就會揮發。
    • 要能有效記憶,必須以「輸出」為前提。以「輸出」為目標去學習、找資料,才能有結構地找資料。
    • 「輸出 = 輸出 + 輸入」(因為聽到自己復述的聲音,等同於再輸入一遍),而為了要講給別人聽,大腦會形成「鏈接」,起碼可以記 3 天。講越多遍、記憶越深刻。
    • 寫文章、教別人。別人會忘記,但你會記得!

「要如何開始?」

  • Xdite 老師提供的新 ORID 寫法:利用 16 格筆記,O、R、I、D 各寫 4 列。

  • 人類面對電腦時,思緒容易飄散;如果是面對有格子的白紙,有利於讓思緒集中、清晰。

「如何達成目標?方法是什麼?」

  • 針對大項目擬定計畫:

    • 短期目標,再一一寫步驟。寫的過程中會發現需要做、不需要的事。
    • 拖延症:因為恐懼未知,心裡會形成負擔。但當「未知」變成「已知」時,會比較有把握(知道自己怎麼作、花的時間、優先度)。
  • 「三大要點、五個小點」:先要寫一個大要點、三到五個小點,讓大腦暖機。(e.g. 老師的講稿,看標題提取記憶,內容在寫下講稿時就已經逐漸連成記憶了。)

  • 先寫文字稿再作幻燈片,不然容易絆倒。

  • 人是可以控制自己的意識流的,關鍵在讓大腦降速:打草稿、寫筆記。

「面對很多項目怎麼辦?」

  • 一口氣在紙上列下代辦事項 To-do List,分為:近期、遠期,先作小項目。

  • 用手跟用筆!用手跟用筆!用手跟用筆!(再次強調)

「大家都是剛學、零基礎,為什麼有些人衝很前面?」

  • 這些人可能每天作一、兩件事,如果你慌張,或作不到,可能是你沒有計畫。請在直播後馬上行動!

(e.g. 陳慧娟學姊,隻字不差地踐行 Xdite 老師的話。)

「關於創業,Xdite 老師一開始是怎麼起步的?」

  • 「資金、團隊」是一個錯誤的假設,所謂「創業成功、初期存活」的定義是:你要賺到錢,而不是作出產品。因為你不一定要產品才能賺到錢。
  • Product Market Fit 很重要。你做出的產品、市場願意付你錢,然後再用這筆錢投資自己。

    • 毛利要高!
    • 毛利率(毛利占銷售收入的百分佔比)的計算方式:(售價 - 成本)/ 售價 = 毛利率。 例子:售價($100 )- 成本($30) / 售價($100) = 70% 毛利率。
    • 毛利率最好要大於 50%,這樣不用有必須銷出很多的壓力,或是因為爭取渠道而被迫降低售價。
    • 不應該讓售價接近成本價,會入不敷出、養不起人、挫敗感很大。
  • 作產品三個大條件

    • 專家:你必須要是該領域的專家。
    • 市場稀缺,在本地市場尚未被滿足,這樣即使不是專家,也還是有機會。
    • 察覺市場變動:觀察到即將出現的需求。
  • 靠創投是不靠譜的。為了得到投資而硬擠出假數據、報告,無助於真正的產品生長,也不可能養出好的團隊。

  • 創投傾向投資 A 輪公司,種子輪項目不吃相,因為沒有項目指標(符合市場的產品)。

  • Culture 很重要:有理念的產品才能吸引相同理念的人加入。(e.g. 全棧營團隊的使命感。雖然大家不是資深工程師,但靠著使命感還是能互相幫助、盡全力打造好產品。)沒理念,會導致各種坑(內鬥、只在乎福利等等),企業無法延續生命。

  • Landing Page:開宗明義說要賣產品、收錢,如果沒人理你,表示不是一個 solid idea,沒戲。

    • Xdite 老師從一位南非創業家學到的,先作一個 Landing Page 說要開班授課。得到迴響,藉此找到市場需求。
    • 如果 Landing Page 失敗,至少不會浪費寶貴的生命和時間。

Q&A 筆紀

  • Q: Xdite老師,在做魔改大賽中發現自己的基礎還是不紮實,是不是應該多做幾遍rails101呢?

    A: 不要回去練 Rails101!重新寫會掉入一個陷阱:直接放棄。你要作的事情是:寫下你「差的地方」,寫 10 個。接著去找對應的教材,一個個學、一個個劃掉。不要一直「重練基礎」,重來不會比較好,你要作的是改正缺點!(珍惜生命)

  • Q: 網頁部署在 Heroku 網速很慢。

    A: 之後會教青雲、阿里雲的部署,目前請先將就 Heroku。不要浪費時間折騰別的,只會增加挫折感,教材的編排是有道理的。

  • Q: 如何顯示 PPT?

    A: 拆解思路:

    • 把原檔放上去(X),將 PDF 拆成圖片(O)
    • 找 Gem 幫你拆圖
    • 再找有沒有外掛可以輪播圖
  • Q: 有沒有學好 CSS 的捷徑?

    A: CSS 沒有捷徑,最快的方式就是改你自己想要的功能。千萬不要回去看書,你會崩潰!請直接抄別人的,然後微調觀察 Class 屬性是在幹麻。Box(Padding、Margin)是必學。

  • Q: 怎麼樣作移動端的自適應?

    A: 用關鍵字「Bootstrap RWD」搜尋,可以找到移動端自適應的資源。

本次直播延伸閱讀

[工商服務區塊]

如果你喜歡我的魔改大賽作品 Quick Hunt,或是覺得我的 Logdown、論壇的分享對你有幫助,可點此投票給予肯定。希望能得到你寶貴的一票,也歡迎你隨時私訊我交流!

[分享] 讓網站支援 Google Map 顯示(圖解)

就如同先前分享過的「切換多語系」功能,這次新添加的「依照工作地點自動生成、顯示 Google Map」依然不是一個 MUST HAVE 功能,但覺得 Google 等大公司的職缺信息都有放一張小地圖,實在太帥了,所以還是硬耗了一天時間折騰。這篇文章濃縮了實裝方式,讓大家少走點冤枉路。如果覺得這篇教程有用,又或是你願意鼓勵支持,歡迎至:我的作品頁面 點下「支持TA」

  • 本篇分享以 Job Listing 教程的代碼作示範,為了節省篇幅,只在 admin/jobs 中添加 Google Map 相關的修改。如果你要在其他頁面顯示,可以照著步驟依樣畫葫蘆。
  • 本篇教程的 GitHub 代碼參考


Step 1. 幫 Job 添加必要欄位(地址、緯度、經度)

在終端機執行:

$ rails g migration add_address_to_job

app/db/migrate 資料夾裡找到剛剛新建的 _add_address_to_job.rb,將內容改為以下:

class AddAddressToJob < ActiveRecord::Migration[5.0]
  def change
    #工作地點
    add_column :jobs, :address, :string  
    
    #需要用到的經緯度欄位
    add_column :jobs, :latitude, :float  
    add_column :jobs, :longitude, :float
  end
end

加好後存檔,在終端機執行:

$ rake db:migrate


Step 2. 管理員在新增工作時可以填入地址

先到在 admin/jobs_controller 修改 def job_params

def job_params
    params.require(:job).permit(:title, :description, :wage_upper_bound, :wage_lower_bound, :contact_email, :is_hidden, :address, :latitude, :longitude)
end

新增、編輯工作的表單記得也要加上「地址」欄位。

  • admin/jobs/new.html.erb
  • admin/jobs/edit.html.erb
<%= f.input :address, :label => t('f_address') %>


Step 3. 安裝 gem 'geocoder',將地址轉換為經緯度

在 Gemfile 中加上 gem 'geocoder',功用是「將『地址』轉換為『經度』、『緯度』,並自動填在欄位 」。

  • Gemfile
# gems for google map

gem 'geocoder'

加好之後存檔,到終端機中執行 bundle install,執行完好請重開 rails server。

為了讓 Geocoder 起作用,我們還必須到 Model 中加上以下兩行代碼;這樣 Geocoder 就會在我們建立或更新工作資訊時,將地址轉換經緯度,然後很貼心地幫我們把資料填入稍早建立的欄位:latitudelongitude

  • app/models/job.rb
# converting address

geocoded_by :address
after_validation :geocode

你可以建一筆有「工作地點」資訊的工作,然後進入終端機 $ rails c 確認。

以此截圖為例,即便我們只填了地址 address: "555 Market Street, San Francisco, CA 94105, USA",這筆工作資料的 latitudelongitude 卻有經緯度的數值。這都是多虧了 Geocoder 這個 Gem 唷!


Step 4. 安裝 gem 'gmaps4rails' 以及 gem 'underscore-rails'

經過上一步,我們有了 Geocoder 幫我們把地址轉成經緯度。我們還需要兩個 Gem 才算是準備就緒。

  • Gemfile
# gems for google map

gem 'gmaps4rails'
gem 'underscore-rails'

加好之後存檔,到終端機中執行 bundle install,執行完好請重開 rails server。

  • app/assets/javascripts/application.js
//= require underscore
//= require gmaps/google


插播:取得 Google Map API Key(API 金鑰)

由於我們要利用 Google 大神的 Google Map API 來顯示地圖,我們必須先取得Google Map API 金鑰

  • 點擊連結,網頁打開後,找到「取得金鑰」

  • 點擊「取得金鑰」後,會跳出一個彈跳視窗。把「Select or create project」的選單點開,選擇選單最下方的「Create a new project」後,原本壓灰無法點擊的「ENABLE API」會變成「CREATE AND ENABLE API」,果斷點擊!

  • 等待一下下,看到這個畫面就萬事 OK 了。「YOUR API KEY」欄位的那一串就是你的「金鑰」,可以先記著等下使用。

Step 5. 顯示 Google Map!

首先,我們要修改 jobs_controller.rb,在 def show 中加入生成地圖的相關代碼(新手如我們就先不追究代碼細節,只要知道代碼的功用是拿 Job 的 latitudelongitude 的經緯度資料產生地圖就好 )。

  • app/controllers/admin/jobs_controller.rb
def show
    @job = Job.find(params[:id])

    # 使用經緯度兩個欄位的數值,建立 Google Map

    @hash = Gmaps4rails.build_markers(@job) do |job, marker|
      marker.lat job.latitude
      marker.lng job.longitude
    end
  end

在 views 中加入以下代碼,「Google Map API 金鑰」這時候就要用上了!請務必記得用剛剛申請的金鑰替換代碼中的「你的API金鑰」。

  • app/views/admin/jobs/show.html.erb
<!-- 測試用,顯示工作地點資訊 -->
<p>緯度:<%= @job.latitude %></p>
<p>經度:<%= @job.longitude %></p>
<p>地址:<%= @job.address %></p>

<!-- 顯示 Google Map -->
<div id="map"></div>

<!-- Google Map 相關代碼 -->
<!-- 請先取得 Google Map API Key(API 金鑰),並用取得的 API 金鑰取代「你的API金鑰」-->
<script src="//maps.google.com/maps/api/js?key=「你的API金鑰」"></script>
<script src="//cdn.rawgit.com/mahnunchik/markerclustererplus/master/dist/markerclusterer.min.js"></script>

<script type="text/javascript">
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
  markers = handler.addMarkers(<%=raw @hash.to_json %>);
  handler.bounds.extendWith(markers);
  handler.fitMapToBounds();
});
</script>

另外,有注意到剛剛貼的代碼中有一行 <div id="map"></div> 嗎?我們還需要到 application.scss 檔設定一下 map 這個 ID 的 CSS 屬性,這一步不單單只是為了頁面的排版,也是為了畫出一個範圍顯示 Google Map (像是準備一塊畫布用來繪製 Google Map);如果沒有設定 widthheight,就無法顯示唷!

  • app/assets/stylesheets/application.scss
// Google Map
#map{
    width:80%; //寬,必須要有!
    height:250px; //高,必須要有!
    margin: 40px;
    margin-left: auto;
    margin-right: auto;
}

以上步驟作完後,回到網頁重整一下,依照該筆工作的「地址」資料生成的 Google Map 就出來了!


Step 6. 解決「使用者必須要刷新頁面,地圖才會顯示」問題

別高興得太早,在測試後,我們發現一個大問題:「使用者必須要刷新頁面,地圖才會顯示」。

把幾個關鍵字「rails google maps load issue」丟給 Google 大神求援時,發現早已有多名 Rails 開發者哀嚎過了。長話短說,之所以會有這個問題,是因為 Rails 的 Turbolinks 造成(欲知詳情,請見:Pros and Cons of Turbolinks in Rails 4 Applications。)。最簡單、暴力的方式就是到 applicaton.js 中把 //=require turnolinks 這一行給刪了。

  • app/assets/javascripts/application.js

刪除後,就能解決「使用者必須要刷新頁面,地圖才會顯示」問題。點開職缺,就可以看到 Google Map 顯示了。大功告成!

  • 實際運用在作品中可以達到以下效果:

參考資料


如果覺得這篇教程有幫助,又或是你願意給我一些鼓勵和支持,歡迎至:我的作品頁面 點下「支持TA」

目前進行中 & 過往 Logdown 分享:

[分享] Global Team Online Meetup 參與方式及 zoom.us 基本操作

關於 Global Team Online Meetup

每週二、四、六的晚上 9:00(UTC+8)有固定的線上 Meetup,利用 zoom.us 連線進行。

如何加入 Online Meetup

軟件需求

  • zoom.us
    • 主要用途:Meetup 在 zoom.us 上進行。
    • 加入方式:下載 zoom.us;參與 Meetup 建議使用桌上型、筆電裝置,方便 Meetup 進行時的相關操作(詳見下方)。

社群需求

  • 微信

    • 主要用途:關注 Meetup 相關消息。每週二、四、六,文志鵬班長會事前將參與 Meetup 要用到的 zoom 連結發至群上。
    • 加入方式:請至文班長在交流論壇的 【Global Team】4月线上meetup报道贴【每周246】,掃碼加入 Global Team online meetup 微信群。
  • Slack

    • 主要用途:發問問題;Meetup 開始之前,請將問題整理、發至 Slack 的 #globalmeetup 頻道。
    • 加入方式: 開啟 Slack,搜尋 #globalmeetup,點擊 Join Channel 加入。

Online Meetup 流程

Online Meetup 開始前:

  • 將問題發至 Slack #globalmeetup,想想自己這週的進度、可以分享的內容(概念、工具、坑),帶著一顆交流分享的心(?)加入。

  • zoom 連結 & 加入
    文志鵬班長在 Meetup 當天會將 zoom.us 連結,發微信 Global Team online meetup 群上。點擊連結即可開啟 zoom.us 軟件、加入 Meetup。

Online Meetup 進行中:

  • Part 1. 自我介紹
    依序輪流。簡單說介紹自己:「我是某地區的誰誰誰,目前進度在哪哪哪。」,跟大家打聲招呼,讓大家認識你。

  • Part 2. 分享「兩最一坑」
    依序輪流。跟成員們分享你的收穫(工具、概念)、你在學習過程遇到的坑。

  • Part 3. 交流、問題時間
    不論是技術性、非技術性的問題,都歡迎你提出來與同學們討論,或請教前期學員(如文班長、近期邀請的一期嘉賓)的意見。

參加 & 基本 zoom.us 操作

Step 1. Meetup 前到 Global Team online meetup 微信群,點擊文班長準備好的連結。

Step 2. 點擊連結後,會開啟瀏覽器、彈跳視窗,點擊「開啟『zoom.us』」。

Step 3. zoom 會議開啟,順利加入 Meetup!

  • 右側欄位(綠色、橘色框框處)

    • 與會者:主持人會依照與會者名單,由上至下依序點名。 [補充] 鼠標移至自己的欄位,會出現「更名」選項;使用全棧營的用戶名稱或本名,能讓大家更快認出你唷。
    • 對話:過程中有要分享連結、臨時追加問題,可以利用對話視窗。(「離開會議」後就找不回對話記錄了,過程中記得記下,或是 Meetup 結束後備份再離開。)
  • 工具列(左下方紅框框處)

    • 解除靜音:發言時,點擊此處「解除靜音」;沒有發言的時候,要記得保持靜音唷,不然鍵盤聲或周圍環境的聲音可能會影響到主持人或其他同學的發言。
    • 啟用視訊:如果不想露臉,可關閉視訊。
  • 工具列中間(中間下方淺藍框框處)

    • 對話:點擊開啟右側欄位的「對話」。
    • 與會者:點擊開啟右側欄位的「與會者列表」。
    • 共享螢幕: 點擊後選擇要分享的畫面,就可以讓 Meetup 成員們看到你的螢幕。 ​

    共享屏幕時,上方會出現一個操作選單,要結束共享時,只要點擊「停止共享」即可中止。

    [補充] 分享屏幕時,可以利用「註記」選單上的功能畫記、標示重點給同學看。

Comments