一開始聽到 Model/ORM/Active Record 這三個東西時,
我心裡的OS是:
“龍哥,可以請你說中文嗎?”
“什麼?!已經是中文了嗎?!” 囧...
簡單來說Active Record是...
Active Record 就是透過ORM的概念建立起來的框架。
姆...有點難以理解?慢慢往下看吧!
上面這張圖在講的是一種常見的網路攻擊叫做 SQL injection,
就是在傳輸到網站伺服器裡的資料裡直接寫 SQL 語法,從而達到某些特定目的。
好一點就只是資料被竊取,狠一點,就像是圖片裡說的,直接刪除所有的資料。
而透過ORM的框架,我們可以避免這種慘劇的發生。
還記得昨天介紹的表單(form)嗎?通常我們從 form 表單裡接收到的資料(data),rails會將這些data打包成一包params
來傳遞,但是這包 params
並不能直接拿來使用喔!
如果你這樣寫,是會噴出錯誤訊息的喔!
user = User.create(params)
這是rails 為了防範SQL injection所做的設計;
所我們必須改寫成下面這樣:
clean_params = params.require(:user).permit(:name, :gender, :email)
user = User.create(clean_params)
透過require
和permit
讓rails知道,我們是要讓哪些資料被存入資料庫;
這樣一來,資料才能順利地被寫入資料庫喔!
在rails裡,對Model的命名慣例是這樣的:
Model/class | 檔案名稱 | 資料表/schema |
---|---|---|
Cat | cat.rb | cats |
Post | post.rb | posts |
CartItem | cart_item.rb | cart_items |
像上面的例子,我們建立了一個 Model Cat,
這就是用慣例產生的樣子:
#cat.rb
class Cat < ActiveRecord::Base
end
當然,如果你真的不喜歡遵守COC,你也可以這樣做:
class Cat < ActiveRecord::Base
self.table_name = "CAT"
end
class Cat < ActiveRecord::Base
self.primary_key = "cat_id"
end
既然有了資料表,我們就可以對他進行基本的CRUD操作。
CRUD 是四種資料操作的簡稱:Create, Read, Update and Delete,
分別是新增、讀取、更新與刪除。
新增資料的方式有兩種:
user = User.create(name: "Vegeta", age: 35)
user = User.new do |u|
u.name = "Goku"
u.age = 35
end
user.save
需要搭配save方法,才會將資料寫入資料庫喔!
讀取資料的方法有很多,底下僅簡單列出一些:
#慣例上,如果選出來的資料會是多筆時,變數名稱我們會用複數來表示
users = User.all
user = User.find_by(name: 'Vegeta')
user = User.where(gender: 'male').order(age: :desc)
更新資料也有兩種寫法:
user = User.find_by(name: 'Vegeta')
user.name = 'Incha'
user.save
user = User.find_by(name: 'Vegeta')
user.update(name: 'Incha')
user = User.find_by(name: 'David')
user.destroy
在建立資料時,有時我們會希望某些欄位有條件限制,在rails中,
我們可以透過設定 validation 來達到我們要的目的:
class User < ActiveRecord::Base
validates :name, presence: true
validates :age, numericality: { greater_than_or_equal_to: 0 }
end
上面寫的兩個validates,意思分別是:
presence: true
)。numericality
),而且必須大於或等於0({ greater_than_or_equal_to: 0 }
)。還是有點看不懂? validates 其實也是個方法:
validates(欄位, 條件)
讓我們來還原上面那段真正的樣子:
class User < ActiveRecord::Base
validates(:name, {presence: true})
validates(:age, {numericality: { greater_than_or_equal_to: 0 }})
end
這樣應該比較好理解一些了吧!
今天對Active Record的介紹這邊啦!!
鐵人賽,我們明天再見!
參考資料:
Active Redord - RailsGuides中文版
Active Redord - RailsGuides