# 1. new + 屬性賦值 + save
order = Order.new
order.name = "virusswb"
order.email = "asdf@example.com"
order.save
# 2. new + 塊語法
Order.new do |o|
o.name = "virusswb"
o.email = "asdf@example.com"
o.save
end
# 3. new + Hash 參數
order = Order.new(name: "virus", email: "adf@example.com")
order.save
# 4. create:創建並保存(推薦)
order = Order.create(name: "virus", email: "adf@example.com")
# 5. 批量創建
orders = Order.create([
{ name: "virus1", email: "111@123.com" },
{ name: "swb2", email: "222@123.com" }
])
# 返回數組,包含所有創建的對象(含 ID)
# 6. 從表單參數直接創建
@order = Order.new(params[:order])
id 默認自增整數,無需手動賦值。save 返回 true/false;save! 失敗拋出 RecordInvalid。create 總返回對象(需檢查 errors 判斷成敗);create! 失敗拋異常。# 拋出 RecordNotFound 異常 order = Order.find(27) # 返回 nil(推薦控制器用) order = Order.find_by(id: 27) order = Order.where(id: 27).first
# 任一 ID 不存在拋異常 orders = Order.find([1, 5, 10]) # 安全版本 orders = Order.where(id: [1, 5, 10])
# 單列
Order.find_by_name("virus")
Order.find_all_by_name("virus")
Order.find_last_by_name("virus")
# 多列
Order.find_by_name_and_email("virus", "a@b.com")
Order.find_all_by_name_and_status("virus", "paid")
# 帶異常版本
Order.find_by_name!("virus") # 不存在拋 RecordNotFound
等價關係:
Order.find_by_name("virus") == Order.where(name: "virus").first
Order.find_all_by_name("virus") == Order.where(name: "virus")
Order.find_by_name_and_email(n, e) == Order.where(name: n, email: e).first
# 找到返回,否則 new(不保存) cart = Cart.find_or_initialize_by_user_id(user.id) cart.items << new_item cart.save # 找到返回,否則 create(直接保存) cart = Cart.find_or_create_by_user_id(user.id)
# 參數化查詢(安全)
name = params[:name]
Order.where("name = ?", name)
Order.where("name = :name", name: name)
Order.where(name: params[:name]) # Hash 直接傳入
# LIKE 模糊查詢
User.where("name LIKE ?", params[:name] + "%")
# 選擇特定列
Order.select("name, email").where(name: "virus")
# 排序、分頁
Order.where(name: "virus").order("name, email DESC").limit(10).offset(20)
# 關聯預加載
Order.includes(:line_items).where(name: "virus")
# 連接查詢
LineItem.select("li.quantity")
.joins("INNER JOIN products pr ON li.product_id = pr.id")
.where("pr.title = ?", "Programming Ruby")
# 聚合統計
Order.average(:amount)
Order.maximum(:amount)
Order.minimum(:amount)
Order.sum(:amount)
Order.count
# 分組統計
Order.group(:state).maximum(:amount)
# => [["TX", 123456], ["NY", 3456]]
# 唯讀對象(不可保存)
Order.readonly.where(...)
# 使用 joins/select 自動標記 readonly
orders = Order.find_by_sql("SELECT name, pay_type FROM orders")
order = orders.first
order.attributes # => {"name"=>"shi", "pay_type"=>"check"}
order.attribute_names # => ["name", "pay_type"]
order.attribute_present?("address") # => false
# 併發場景:獲取最新數據
loop do
puts "Price = #{stock.price}"
sleep 60
stock.reload
end
# 1. 實例修改 + save
order = Order.find(10)
order.name = "swb"
order.save
# 2. 更新單個屬性(繞過驗證)
order.update_attribute(:name, "newname")
# 3. 更新多個屬性(觸發驗證)
order.update_attributes(name: "newname", email: "newmail")
order.update(name: "newname", email: "newmail") # Rails 4+ 別名
# 4. 類級別更新
Order.update(12, name: "newname", email: "newmail")
# 5. 批量更新(單條 SQL,繞過驗證/回調)
Order.update_all("price = 1.1 * price", "title LIKE '%java%'")
# 返回受影響行數
| 方法 | 層級 | 觸發回調/驗證 | 返回值 | 異常處理 |
|---|---|---|---|---|
delete(id) | 類 | ❌ | 受影響行數 | 不存在不報錯 |
delete([1,2,3]) | 類 | ❌ | 受影響行數 | 不存在不報錯 |
delete_all(conditions) | 類 | ❌ | 受影響行數 | 無匹配返回 0 |
destroy(id) | 實例 | ✅ (before_destroy/after_destroy) | 對象(凍結) | 不存在拋 RecordNotFound |
destroy_all(conditions) | 類 | ✅ | 對象數組 | 無匹配返回 [] |
destroy,確保驗證、回調、關聯級聯刪除(dependent: :destroy)生效。delete/delete_all 直達 SQL。| 方法 | 成功返回 | 失敗返回 | 驗證 | 回調 |
|---|---|---|---|---|
save | true | false | ✅ | ✅ |
save! | true | 拋 RecordInvalid | ✅ | ✅ |
create | 對象 | 對象(含 errors) | ✅ | ✅ |
create! | 對象 | 拋 RecordInvalid | ✅ | ✅ |
ActiveRecord CRUD API 設計兼顧了便利性與安全性:
create/update/destroy,自動處理驗證與回調。where 鏈式調用,告別 find_by_sql 除非極其複雜。update_all/delete_all 跳過回調,謹慎使用。reload 或樂觀鎖(lock_version)保證數據新鮮度。「讓 ActiveRecord 做它擅長的事:將業務語言翻譯為 SQL,而不是手寫 SQL。」