Medium你很好,但是…

寫在頭前

想換個地方寫寫,Medium這邊應該多少會同步更新(吧?),它還是有好處啦,例如追蹤其他人的文章是方便的。
推力:Medium真的不好寫程式碼,沒有Markdown。
拉力:可以建立自己的網域,有Markdown。

前置安裝環境

以下我會盡量手把手教學。
有寫到 $ 字號開頭的指令,是在終端機進行指令操作,與程式碼無關。
我的安裝環境,是macOS (Mojave 10.14.6),使用iTerm (oh-my-zsh)。

我們需要先安裝
1. Node.js
2. Git
如果是macOS,而且在編譯上出現問題,可能還需要
3. Xcode

這些我都裝過了,所以容我跳過,可能改天換電腦再來加入這系列的文章。
如果你是 Ruby on Rails 的開發者,可能已經安裝過這些了。
那我們用終端機指令檢查一下 …


「你可以教教我愛客繩纜線嗎?」

以下我先用我自己對Rails Guide(v6.1.0)的翻譯,作為開頭介紹---

1. 什麼是Action Cable?

Action Cable將WebSocket技術與Rails本身的其他部分無縫地整合在一起。
它用Ruby編寫即時功能,並保持與Rails其他部分一樣的風格與形式,同時也有效能和可擴充性。
它對客戶端(網頁的瀏覽器)的JavaScript框架以及伺服器端的Ruby框架(就是Rails)提供全端的服務。
你可以對Active Record(或其他你運用的ORM)所編寫出來的領域模型進行存取。

2. 技術名詞

2.1 Connections (連接)

connection 是與客戶端形成關係的基礎。
一個Action Cable伺服器可以處理多個connection實體。
一個WebSocket connection對應一個的connection實體。
使用者可用多個瀏覽器分頁或不同裝置,在你的程式(或者說網站)開啟多個WebSocket服務。

2.2 Consumers (接收者)

WebSocket connection的客戶端就叫做consumer。
在Action Cable裡,consumer是客戶端的JavaScript框架所產生的。

2.3 Channels (頻道)

每個consumer可以反過來訂閱多個channel。
每個channel封裝一個邏輯工作單元,與MVC架構裡的Controller相似。
舉例,你可能有一個ChatChannel和一個AppearancesChannel,而且consumer可以訂閱這兩個頻道中的一個或兩個。
一個consumer至少會訂閱一個頻道。

2.4 Subscribers (訂閱者)

當consumer訂閱channel時,被該channel當作是subscriber。
subscriber和channel之間的連接,叫做subscription。
(編按:呼應第一句)一個consumer可以被它訂閱的channel多次地當作(意思就是,重複被當作新的)subscriber。(編按:這點一開始看不懂沒關係,如果實作了聊天室,就可以驗證重複訂閱這點,之後可能會要用 consumer.subscriptions.subscriptions[0] 之類的東西)
以2.3的舉例繼續說明,consumer可以同時訂閱多個chat room(同樣都在ChatChannel下)。
請記住,一個現實世界的使用者可用多個瀏覽器分頁或不同裝置,同時成為多個consumer。

2.5 Pub/Sub (推播/訂閱)

Pub/Sub,全名Publish-Subscribe,是指一種訊息佇列模式,據由該佇列,信息發送者(Publishers)將數據發送給抽象類別(abstract class)的接收者(Subscribers),而無需指定個別的接收者。
Action Cable使用此方法在伺服器端和多個客戶端之間進行通信。

2.6 Broadcastings (廣播,Broadcast的名詞)

Broadcasting是Pub/Sub的鏈接(意指使用broadcast 的動作),廣播者發送的任何內容都直接發送到指名的channel,該channel串流的subscribers(頻道訂閱者)接收。
每個頻道可以串流零個或多個Broadcastings。

References

Guides.rubyonrails.org — Action Cable Overview


開始跑專案以後,我才學會的事

之前的自我練習真的太少了,那就來補吧。
這篇可能沒有跟Meta Programming沾到邊。

一開始學Ruby,可能會問:「啊你怎麼知道有這方法可以用?」
除了「你不會知道你不知道的事」之外的回答,就是「看文件」。

那Rails呢? 「看文件Guide

找飯店? 「Trivago」

查詢 這個方法 寫在哪

言歸正傳。
學到後面Ruby的指令越用越少了,因為一直在碰Rails。
再者,可能是它們寫起來很像人話,所以有時候想到一個方法,不知道能不能用,除了看Doc,還有別的方式。
查詢方法寫在哪,我們先在Rails console試,在這裡面可用Ruby和Rails的指令。
例如要找 blank? 這個方法,可以看它寫在哪,範例如下:

2.7.0 :007 > "a".method(:blank?).source_location
=> ["/Users/apple/.rvm/gems/ruby-2.7.0/gems/activesupport-6.0.3.4/lib/active_support/core_ext/object/blank.rb", 121]

發現是寫在 active_support ,一看到這些「Active XXXX」,很明顯地這個方法是寫在Rails。
接著我們試著在irb查,這裡面只能用Ruby:

2.7.0 :003 > "a".blank?
Traceback (most recent call last):
5: from /Users/apple/.rvm/rubies/ruby-2.7.0/bin/irb:23:in `<main>'
4: from /Users/apple/.rvm/rubies/ruby-2.7.0/bin/irb:23:in `load'
3: from /Users/apple/.rvm/rubies/ruby-2.7.0/lib/ruby/gems/2.7.0/gems/irb-1.2.1/exe/irb:11:in `<top (required)>'
2: from (irb):2
1: from (irb):3:in `rescue in irb_binding'
NoMethodError (undefined method `blank?' for "a":String)

嗯…看來是找不到呢。
所以Ruby裡沒有 blank? 這個方法,結案。

查詢類別

以空字串 "" 為例,
一樣在Rails console查詢:

2.7.0 :008 > "".class
=> String

.class 查詢前面的物件是什麼類別。

試試在irb查詢:

2.7.0 :011 > "".class
=> String

但其實上面兩個查詢class,用在哪裡是沒差的,別被誤導,只是想確認兩個會是一樣的結果而已。

延伸閱讀

Ruby on Rails 中的 IRB、Pry、rails console 差別
第 12 屆 iT 邦幫忙鐵人賽- Metaprogramming Ruby and Rails 系列
[Ruby] nil?, empty?, blank?, present?, any? methods
.nil? .empty? .blank? .present? 傻傻分不清楚?


開始跑專案以後,我們才學會的事

組員A: rails db:migrate 後,又修改檔案

繼上一篇的操作,我又學會了另一件事,這篇來講一下這個議題。
這個狀況是團隊協作時發生,自己做的project不會發生的。

我會用事情發生的時間順序描述一下這狀況:

  1. 組員A從devise套件做了一個檔名 devise_create_users.rb的migration檔。
    可以稍微看上圖的第25~28行,這時候還是註解起來的。
    因為組員A想說,devise套件的confirmable還不需要用到,於是就在這樣的migration檔的記錄下,下了指令 rails db:migrate
    schema.rb 檔留下了這次migrate的生成紀錄,這一刻, schema.rb 檔裡並沒有confirmable的那幾行。
  2. 經過了2天的進度,組員A忽然發現他需要做devise的confirmable。
    於是他把前天做過 db:migrate 的migration檔裡,註解的confirmable解開來。把註解解開,所以他

對「已經做過 db:migrate 的migration檔」進行了「修改」。
這是新手常踩的雷

其實也不是不能修改,也許可做 db:rollback ,然後再對這個migration檔修改,再 db:migrate 一次。

3. 接著,他以為註解打開就可以做了,於是進行了 db:migrate
然後他發現他要的欄位都沒加入 schema.rb

4. 下意識地,組員A想到,可以做一個 add_column_to_users 的migration檔,然後進行 db:migrate ,他成功把他要加的欄位加進 schema.rb 檔。
於是這一連串的動作,產生了

兩個migration檔同時存在,且檔案要建立的欄位有重複到的狀況。

請參照下面兩張圖片。


答案借你抄,面試不要太糟糕

昨天進行了履歷健檢,很多人都被問到,想當工程師的動機,這確實也是面試會面對的問題。

要去哪裡?

上課到現在,我確實沒有好好認真想過這個問題,履歷也忘記寫,要應徵的是什麼職缺。
捫心自問,是因為還沒很肯定自己到底要往前端還是後端走。

後端起步薪水較好,不過Ruby on Rails的職缺並不多,雖然也是有寫Python的公司願意收,可能開拓到那個當紅的語言,但這機會是比Rails職缺本身的數量還少。
前端工作機會多,但想必多就會雜,就算很快找到工作,也許很快就發現公司並不理想,無法同時提升技術力;且目前市場上太多人在學,可能因此,起薪平均大約比後端少1萬多。

想太多了,現在能力都不知道有沒有人願意收,由不得我選,兩邊都要努力。
而且大大們都說,前端還是要懂點後端,後端也要懂點前端。

為何而來?

今天晚上待在默默會,兩三個同學們發現教室後面坐了一位女力班的學員,讚嘆她切版很厲害,比我們上個月,做得還要好,我們那時也是第一次切整頁。(喂..還有時間找學妹搭話呀…)
同屆的幾位自嘆不如,不敢承認自己是Amos教的了。
看來我們這屆的美德就是謙虛,而且很願意給人掌聲。
這學員說女力班快上完了,有講到RWD,還有帶到一點Javascript。
因為同學們的這段搭話,當我獨自走在228公園漆黑的路上,想到大家都一樣是從各行各業來,那自己是從哪來的?

和設計相似的

回想到更早以前的自己,發現工程師,和設計人有些共同點。
- 同樣會為了技術而投入,而這些技術也只有懂的人懂(聽起來好像廢話),遇到懂的人,會有共鳴。
- 和舞台都有點關係,更深層面來講是需要肯定。
做設計的不得不,且一定要proposal和參加比賽。現代設計產品通常簡約、婉轉且有時隱晦的,通常最後出來的作品,沒有人看得到過程,只看得到結果;參加比賽是希望得獎,對職涯有幫助,也是一份肯定。
龍哥常講工程師「愛現」,也許是因為工程師這工作的性質,比較像公司的幕後,即便施展了技術力,但鮮少被人懂自己的技術多厲害,因而產生的一種補償心理。
(又或者,這是龍哥自己的心理投射?)
GitHub和技術部落格,就是工程師們的舞台。

和設計不同的

設計師比較偏向獨善其身,沒有不好,這只是職業性質使然。
因為設計所謂的「美感」,需要積累,且交流不來,部分是天份。如果會交流,頂多教你去多看什麼,或多練甚麼,學甚麼工具。
如果讓設計師團隊合作,很常會遇到各有意見,畢竟你說的美不是我覺得的美,分工起來比較像是一起完成意見最多的人的意志。

工程師最特別的文化就是分享技術文章了,技術可以被複製(能力不行啦)。
而另一點是模組化思維,一個project可以前、後端切分開來。且配合前一點的技術分享,一起提升能力,可以讓project做得更好更順暢,分工可以完成得更快。
會動就是會動,說1就是1,沒有就是沒有。不會有不認同結果的狀況,答案是有的,且不同的解答方向不會差太多。

總結我現在

我想我最喜歡的兩點,是搞懂一段code、學習重點的瞬間,還有分享技術、所學的寫文章過程。


開始跑專案以後,我才學會的事

在AstroCamp分組、確定要做的網站之後,大家開始要rails new出專案,並且開始實際跑團隊協作了。
因為後面會用到Heroku的服務,所以我們這組在一開始就決定把Database設為pg。然後新手會遇到問題就來了😊

rails db:create

之前上課練習的專案都還在用Rails給的sqlite,一般clone或下載了新的專案下來,只要跑rails db:migrate就可以,sqlite可以只做到這步。
但PostgreSQL不是sqlite。
你得先下指令

$ rails db:create

同學的文章裡有提到這一步,在安裝PostgreSQL的時候,也是這指令和先前的sqlite有所區別。
如果database是使用MySQL,也是要先create起來。

是說,剛clone下來的專案才要做 rails db:create 。
後續fetch專案分支進度以後,已經有 schemaseed,可以試下指令:

$ rails db:setup

學長的文章,其效果等於 db:create + db:schema:load + db:seed

然後再跑sqlite也要做的

$ rails db:migrate

PG::ConnectionBad

班上有同學(也是用Macbook)在做 rails db:create 時遇到了 PG::ConnectionBad 的問題,但我沒辦法在這部份加入文章,因為我的Macbook沒遇到這問題,所以只能先簡單找個文章備註一下。

References

Sqlite vs. MySQL vs. PostgreSQL: A Comparison of Relational Databases
Changing sqlite to PostgreSQL in ruby on rails
我想要把 rails 的內建資料庫改成postgreSQL
在 Rails 專案安裝 PostgreSQL


當你看到,覺得有印象,卻想不起來那是什麼

||=

在寫上一篇的時候,印象中隱約看到了寫不太對的地方,我應該是鬼遮眼了,但真實想法應該是想先放一邊吧.我錯了,對不起…
現在來講講正確的 ||=

來看看這個用法

a ||= b

然後把這寫法先忘掉,想一下,我們上一篇提到,這一行是要做什麼?

如果a不是 nil或 false的話,那就維持a本來的值,不然就把b的值指定給a

這句話,不用上面的寫法,我應該會直接寫下面這一大串

if a then
a = a
else
a = b
end

「如果a有值的話,那a維持不變,a就是a;否則把b指定給a」
好,這樣滿清楚的,那再用用看符號,看要怎麼寫

# 先寫這樣
a = a || a = b
# 左邊的 a = a 好像有點囉唆,直接寫a吧# 於是變成這樣
a || a = b

OMG! 原來是這樣

原來 a ||= b 其實是 a || a = b 啦!

不過這是我自己的理解和記憶思路啦,我的解釋不一定是對的,相信你從上一篇有看出來了.

上一篇提到 += ,我那時以為只是把符號輪轉位移的寫法,深入研究後,才發現案情不單純.還好我為你踩雷了,不客氣.
有時間的話建議看看下面這幾篇吧.

Reference

建議先看這篇
Day09 — 超級經典面試題: Ruby的 a ||= b (or-equals)是什麼意思呢?
Ting Ting學姊寫的文都好厲害,又完整又打到我們這些初學者的痛點,身為五倍學弟,倍感壓力呀!

Day10: Ruby中的Conditional Assignment Operator: x ||= y(or-equals)
這是另一位五倍學長,整理得也滿完整的.

再來一篇外文的,共同編輯人是Ruby爸爸-松本行弘,這沒問題了吧,設計者自己出來提,這篇舉的例子稍微難看懂,就看看吧.
The Ruby Programming Language by David Flanagan, Yukihiro Matsumoto-Assignments


當你看到,覺得有印象,卻想不起來那是什麼

Ruby裡的 ||= 和 +=

在學先修課程Ruby時,看到了+= ,這裡簡短舉例說明一下

a = a +1
# 把a+1指定給a

也可以寫成

a += 1

在寫法上,就是把 = 右邊的 a 搬到左邊,然後把 += 倒裝放。

而關於 ||= 的簡短解釋如下

如果a不是 nil或 false(有賦值),那就維持a本來的值,不然就把1設定為a的值

下面用連續一字線上下包起來的是錯誤示範,但我想我應該不是第一個踩雷的,所以還是留著這個錯誤。
— — — — — — — — — — — — — — — — — — — —

a = a || 1
# 這是錯的解釋,你要是忽略我的警告,學到錯的,我也沒辦法了

— — — — — — — — — — — — — — — — — — — —

至於正確的 ||= 是什麼? 我打算另外寫一篇

上課看到 ||= 這符號時,我呈現已忘記的狀態。
老實說,在Ruby的先修對 ||=沒太多印象,可能是因為我做題目和練習太少,只有碰到+= 。先承認,因為以後還是要面對問題。
當實體課程開始,上到Rails中段,這個 ||= 忽然冒出來,所以有了這篇文章。

Rails裡的 ||= 和 +=

進到Rails以後,有了內建的 increment 方法可以使用,功能和 += 似乎滿像的,還沒深入去了解。而課程到目前做到會員功能,還沒碰到 +=
不過 ||= 已經出現了,來看看下面這段

module SessionsHelper…


以Windows內使用Ubuntu為例

前言廢話-安裝Ruby和Rails的高牆

我:「聽說Ruby On Rails不難學耶!」
安裝了一天之後....
還是我:「算了,我這輩子一定學不了程式」

據龍哥說,很多人開始學Ruby On Rails的時候都會卡在安裝這關,為了不拖累正課進度,他還因此特別在Astro Camp正式開始前,安排了一個時段的安裝課,只為了教大家如何裝好使用環境,Rails也不會真正操作到。

我個人覺得這件事和買電腦很像,需要用到的時候才會需要研究,但真的也需要花很多時間做功課,又有太多生硬、不常使用,甚至日後不大有機會再碰到的知識和名詞。
有些步驟大概需要用一次而已,安裝好就不需要再管了。那部份還是交給龍哥,有興趣安裝Ruby和Rails的,請洽五倍紅寶石

有些步驟日後使用Rails框架的時候還會用到,這一篇就是在描述常用的部分,怕自己忘記,很值得寫一篇記錄下來,同時也當作分享。

因為開始決定寫Medium時,我電腦裡的Ruby和Rails已經安裝好了,所以這篇會直接從Rails開始新專案的環境安裝開始。

開始Rails新專案

1. $ rails new 新專案名稱:建立新的Rails專案
建立完之後,會在下指令的資料夾裡產生一個新資料夾,名稱就是剛剛key的新專案名稱。
有的技術文分享,這邊會編寫作$ rails new app ,我這邊寫 新專案名稱 ,是想表達這名稱是可以任意修改的。

2. 進入專案資料夾
(這步很重要,很多新手急著打指令,就直接跳到下一步了。那樣會跑出錯誤訊息的呀...我一開始設定的時候就是發生這種事)

3. $ rails server或簡寫$ rails s:啟動rails伺服器
成功的話,出現的訊息應有Puma…如下:

=> Booting Puma
=> Rails 6.0.3.4 application starting in development
=> Run `rails server — help` for more startup options
Puma starting in single mode…
* Version 4.3.6 (ruby 2.6.6-p146), codename: Mysterious Traveller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://127.0.0.1:3000
* Listening on tcp://[::1]:3000
Use Ctrl-C to stop

Rails是使用Puma作為伺服器,Puma效能比較好,也是Rails相較於Sinatra這框架效能較好的原因。

4. 上一步出現的訊息有//127.0.0.1:3000,等同於localhost:3000,就是Rails執行的位置。
打開瀏覽器並輸入位置。

5. 在瀏覽器看到類似下方的圖片,一群小朋友在地球上,快樂地站在一起,就表示Rails環境安裝好且成功執行啦!

6. 開是開好了,但怎麼關掉Rails Server? 沒講完這個,大概就跟講起飛不講降落一樣。
在第3步驟的一大串訊息裡的最後一行有寫 Use Ctrl-C to stop ,所以直接按Ctrl + C就可以啦~

中場休息

休息是為了走更長遠的路,把簡單的成長養成一種放鬆習慣,那豈不一舉兩得?

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store