RUBY
一、symbols 字串符號 唯一且不會變動的識別名稱 效能比較好,不需要額外的空間來儲存
字串物件(string)每次都會更新記憶體位置,效能不如symbols但優點是有許多方法可以使用如: reverse, size, downcase
二、 問號跟驚嘆號
在 ruby 定義方法時,問號跟驚嘆號也是方法的一部分。
一般使用問號時,慣例上是表示這個方法會回傳布林值 (true 或 false)
使用驚嘆號,通常是表示這個方法可能會有「副作用」或「驚喜」,例如陣列有個叫做 uniq 的方法,它可以產生一個元素不重覆的新陣列。
uniq 方法會回傳一個新的陣列回來,不影響原來的資料
|
|
但如果你是使用有驚嘆號版本的 uniq! 就不同了,原本的陣列也被改變了。
|
|
三、join、split join 用於將陣列( array )中的元素( element )轉成字串( string )。
split 用於將字串( string )轉成陣列( array )
四、module 與 modle
五、namespace
Rails
一、型態 text(文字) 與 string(字串)
text 是一種二進位,binary 的格式。可以放的字非常多,可能幾千、幾萬個字,可以使用在如文章內文
string 能放的字比較少,使用在文字不會太長的情況,例如文章標題
二、什麼是 migration
一種描述資料表該長什麼樣子的描述檔,可以漸進式的去修改你的資料表
優點: 有紀錄,是一連串的檔案,為資料表的演進過程(欄位變化,新增修改刪除) 可以進行版本控制
如果要使 migration 具現化,在終端機下指令:
rails db:migrate
三、CSRF 攻擊
CSRF (Cross-site request forgery),跨站請求偽造。目的不一定是要取得使用者帳戶的控制權或個資,但可以用其他使用者的名義執行某些操作。
這類攻擊的特點是以使用者身份發起
例如,駭客想刪掉某個 Blog 平台的文章,雖然他沒有這個網站的使用權限,但猜到了後台的路徑: /admin/posts/1
便可以使用 delete 方法來刪除。接著把這個連結包裝成中獎資訊,寄送給有權限且剛好處於登入狀態的 X 先生,當 X 先生點下連結,文章就會透過 X 先生的權限來刪除了。
這個例子中,CSRF 攻擊之所以可以成功,並不是因為駭客獲取 X 先生 的 cookie 資訊,而是偽裝成是 X 先生。
解決方法:
- 檢查 referer 欄位 (可透過檢查 Header 中的 Referer 欄位是否存在及是否為正常流程網域,藉此確認發送端的前一個頁面是否被偽造或合法使用。)
- 加入驗證 token (除了驗證 Cookie 的 Token 之外,還需另外在 Request 中放入隱藏的動態 Token 參數。等同於要求每次的 Request 都必須帶上密碼)
四、什麼是 erb 檔 可以在 HTML 裡面寫 ruby 的程式碼。ERb其實可以用來產生任何文字檔格式,例如CSV、XML、JavaScript等等
五、N+1
N+1 指的是 SQL 撈資料時,明明可以一次撈完 (例如要三筆資料),卻使用逐筆撈資料的方式處理 (每次只撈一筆資料) 1次查詢 + N 次的關聯資料查詢就會讓資料庫效能損失
解決方法:
查詢資料的過程中,使用includes
多撈一點資料回來。變成 1 + 1
六、中控台模式 rails console
rails c
可在裡面修改資料及查詢資料。
跟 irb 本質上沒有太大差別,中控台模式會把整個 rails 環境,包含相關model 、相關套件整個載下來。
而 irb 就是一般 ruby 環境
七、ORM
Object Relational Mapping
目的: 簡化資料庫操作語法
透過物件的方式,去操作資料表,再換句話說, 把物件導向的語法,透過model,轉換成 SQL 查詢語句,對開發人員來說輕鬆很多。撈回來的資料再交給 model 物件化
例如: Book.all 等同於 select * from books
SQL 可以被 ORM 取代嗎?
- 當遇到問題時,比如效能,還是需要在 log (紀錄) 裡看 SQL 的語法,看是否寫錯造成翻譯錯誤。
- 複雜的查詢還是必須使用 SQL 語法
ORM 基本操作 CRUD
C new 新增一筆資料 create 新增一筆資料,並寫進資料庫 (寫入失敗時默默 rollback) create! 同上,但寫入失敗時會噴錯誤訊息 (可使用 beging rescure 捕捉) R first 找出第一筆資料 last 找出最後一筆資料 find:找出單一筆資料,且只能透過id去搜尋。找不到時 find 會噴錯誤訊息 (例外訊息) find_by 找出單一筆資料,且可以透過自訂條件去搜尋。找不到時 find_by 會回傳的值是nil find_each 資料量大時,預設每次抓 1000 筆 all 找出所有資料 select(’name’) 同上,但只選取 name 欄位 where(name: ‘Happy’) 找出所有 name 欄位是 Ruby 的資料 order(‘id DESC’) 依照 id 大小反向排序 order(id: :desc) 同上 limit(3) 只取出 3 筆資料 count average sum maximum 與 minimum U update update_all increment 欄位的值 + 1 (沒有存檔功能,要記得 save) toggle 把原本的 true / false 值對調 (沒有存檔功能,要記得 save) D delete destroy 刪的過程中,有一連串的 callback destroy_all
Scope
把商業邏輯寫到 model 裡 取代 controller 一堆 where 是一種類別方法
八、 MVC
MVC 架構 Model View Controller
流程: 一個使用者,透過 route
(第一線處理 request 的角色,在 rails 裡非常重要) 導到某一個controller
,也許需要調資料(跟model
),也許不用。查完之後(如果需要查詢的話)把資料交還給controller
,用 view
去做頁面呈現 (HTML & CSS)
Model: 抽象層的概念 model 不是資料表,資料表是 table (實體存在的東西)
Controller: 本身是一個 class , 一個一個的 action 就是方法
View: 在 controller acton (透過 model 向資料庫) 拿到的 raw data,搭配畫面跟表單,組成一般使用者可以讀的表格、表單
優點∶ 歸類整齊,易於前後端分工 流程控制: controller 資料邏輯: model 畫面相關: view
View 技術上來說,其實是會回傳 HTML 內容的方法(method、function)
九、資料驗證 前端驗證: 還沒送出去前,在表單用 JavaScript擋下來,缺點驗證是容易被避開 後端驗證: 寫進資料庫之前,如果內容沒填、格式有問題等,把它擋下來。
在 model
層,比如名字欄位必填,可以使用以下的驗證器
|
|
其他在 rails guide 的 Validation Helpers 還有更多可以使用的驗證
不寫在 controller 的原因,每一個 controller 要寫去都要做檢查
model 是整包做檢查
若同時有不同系統存取資料庫的狀況(比如PHP),則無法保證資料一定無誤。這時可以在資料庫本體擋掉,比較安全
如何繞過驗證 c.save(validate: false)
十、 Callback
資料存檔的流程會經過以下流程: save > valid > before_validation > validate > after_validate > before_save > before_create > create > after_create > after_save > after_commit
before_save 資料寫進跟更新都會執行 before_create 資料被建立的時候才會執行
十一、 Active Record
是一種設計模式,本身是一個物件。 每一筆資料包裝成一個物件,並在其增加資料操作邏輯,讓資料的存取更便利
這個物件,由欄位、基本操作、商業邏輯組成
我們可以說 MVC 裡的 Model = 依照 Active Record 模式設計的產物
而 Active Record 是一種 ORM 框架
Active Record ORM Model Database Table
十二、二大哲學
(一) 慣例優於設定 Convention Over Configuration(CoC) 慣例 = 可以少寫不必要的程式碼 學習 Rails ,等於是在學習 Rails 的慣例 例如:
- Model: 大寫、單數
- Table: 小寫、複數
- 每個表格預設會有一個叫做 id 的流水編號欄位
- 在 migration 裡預設會有個 timestamps,在具現化的時候,會轉換成 created_at updated_at這兩個時間欄位,在資料新增或更新的時候自動寫當下時間
- model 跟 table 的對應
pluralize
找出複數名詞的方法singularize
找出單數名詞的方法 比如
"person".pluralize
=> "people"
"people".singularize
=> "person"
若需自定義,在
config/initializers/inflections.rb
設定
- 檔案跟 model 的對應。類別名稱由兩個以上的單字組成時,Model 名稱應要遵循 Ruby 的命名慣例,採用駝峰式命名,而資料表名稱必須採用底線分隔。
underscore
變成蛇式的方法camlize
變成駝峰式 比如
"HappyHour".underscore
=> "happy_hour"
"happy_hour".camlize
=> "HappyHour"
- 外鍵 - 應用資料表的單數形加上 _id 來命名,比如 item_id, order_id。Active Record 會在你建立 Model 之間的關聯時,尋找這種形式的欄位 singularized_table_name_id。
當 model 之間的關連不是用慣例時,必須加上 foreign_key
比如有一個 store 的 model:
|
|
foreign_key 是遵循慣例,所以後面可以省略,但如果是接手別人案子或設計,可能原本不是用 ruby 或 rails 寫的,則需寫出 foreign_key 如下
|
|
-
主鍵(流水編號欄位id) - Active Record 預設會使用一個叫做 id 的整數欄位,作為資料表的主鍵。採用 Active Record migration 來建立資料表時,這個欄位會自動產生。
-
參照值
user:references 會造出 user_id 這個數字型態欄位 會指向 user 這個 model 的主鍵(流水編號欄位id)
(二) Don’t repeat yourself
十三、關聯性
一對一、一對多、多對多 has_one 不是設定,它是一個類別方法,例子中的 store 是它的參數 執行 has_one 後,會動態做出四個方法,比如
|
|
|
|
|
|
十四、 include、extend、reuqire、load
include:include是用於向類中包含模組的關鍵字。它將指定的模組中的方法添加到類的實例中,使其可以調用模組中的方法。
extend:extend也是用於向類中包含模組的關鍵字,但是它將指定的模組中的方法添加到類本身中,使得該類可以調用模組中的方法。
require:require是用於加載其他 Ruby 文件中的程式碼。它可以將其他文件中的類、方法和變量加載到當前文件中。如果該文件已經加載過了,require將不會再次加載。
load:load也是用於加載其他 Ruby 文件中的程式碼。它和require的區別在於,load每次都會重新加載指定的文件,即使該文件已經加載過了。
十五、API
十六、RESTful
十七、CACHE 暫存
十八、 Active Job 背景工作
十九、 前端的 partial 和 helper 差別
二十、Gemfile 的用意?
二十一、 namespace