ruby rails 中对数据库的操作
2012-11-16 16:08
302 查看
转自:/article/7117432.html
其中create和create!就等於
何時使用驚嘆號版本呢?save和create通常用在會處理回傳布林值(true/false)的情況下(例如在 controller 裡面根據成功失敗決定 render 或 redirect),否則在預期應該會儲存成功的情況下,請用 save!或create! 來處理,這樣一旦碰到儲存失敗的情形,才好追蹤 bug。
透過 :validate => false 可以略過驗證
在 Rails3 之前的版本是 user.save(false)
Arel 是 relational algebra” library。但根據 2.0 實作者 tenderlove 的說法,也可以說是一種 SQL compiler。 http://engineering.attinteractive.com/2010/12/architecture-of-arel-2-0/
first, last 和 all
這三個方法可以分別拿出資料庫中的第一筆、最後一筆及全部的資料:
如果資料量較多,請不要在正式上線環境中執行.all 把所有資料拿出來,這樣會耗費非常多的記憶體。請用分頁或縮小查詢範圍。
find
已知資料的主鍵 ID 的值的話,可以使用 find 方法:
find 也可以接受陣列參數,這樣就會一次找尋多個並回傳陣列:
如果找不到資料的話,會丟 ActiveRecord::RecordNotFound 例外。如果是 find_by_id 就不會丟出例外,而是回傳 nil。
find_by_* 和 find_all_by_*
find_by_* 和 find_all_by_* 是 Rails 的動態方法,可以自由用 and 組合,例如:
find_by_sql
如果需要手動撰寫 SQL,可以使用 find_by_sql,例如:
不過在絕大多數的情況,是不需要手動寫 SQL 的。
where 查詢條件
where 可以非常彈性的組合出 SQL 查詢,例如:
其中參數有兩種寫法,一種是 Hash,另一種是 Array。前者的寫法雖然比較簡潔,但是就沒辦法寫出 or 的查詢。注意到不要使用字串寫法,例如
這是因為字串寫法會有 SQL injection 的安全性問題,請改用陣列寫法。
另外,where 是 lazy loading,也就是直到真的需要取值的時候,才會跟資料庫拿資料。如果需要立即觸發,可以接著使用 .all, .first, .last,例如
如果要消去order條件,可以用
例如欄位中有 Binary 資料時,你不會希望每次都讀取出龐大的 Binary 資料佔用記憶體,而只希望在使用者要下載的時候才讀取出來。
如此查詢出來的
預設會批次撈 1000 筆,如果需要設定可以加上 :batch_size 參數。
另一種是直接對類別呼叫刪除,傳入 ID 或條件:
delete 不會有 callback 回呼,destroy 有 callback 回呼。什麼是回呼詳見下一章。
其中我們可以利用上述的 where 條件縮小範圍,例如:
注意 update_attribute 會略過 validation 資料驗證 注意 mass assign 安全性問題,可以透過 attr_protected 或 attr_accessor 設定。
rails
对数据库的一些操作:新增,查询等
基礎操作
如何新增
ActiveRecord提供了四種API,分別是save、save!、create和create!:a = Category.new( :name => 'Ruby', :position => 1 ) a.save b = Category.new( :name => 'Perl', :position => 2 ) b.save! Category.create( :name => 'Python', :position => 3 ) c = Category.create!( :name => 'PHP', :position => 4 )
其中create和create!就等於
new完就save和save!,有無驚嘆號的差別在於validate資料驗證不正確的動作,無驚嘆號版本會回傳布林值(true或false),有驚嘆號版本則是驗證錯誤會丟出例外。
何時使用驚嘆號版本呢?save和create通常用在會處理回傳布林值(true/false)的情況下(例如在 controller 裡面根據成功失敗決定 render 或 redirect),否則在預期應該會儲存成功的情況下,請用 save!或create! 來處理,這樣一旦碰到儲存失敗的情形,才好追蹤 bug。
透過 :validate => false 可以略過驗證
c.save( :validate => false )
在 Rails3 之前的版本是 user.save(false)
如何查詢
ActiveRecord 使用了 Arel 技術來實作查詢功能,你可以自由組合 where、limit、select、order 等條件。Arel 是 relational algebra” library。但根據 2.0 實作者 tenderlove 的說法,也可以說是一種 SQL compiler。 http://engineering.attinteractive.com/2010/12/architecture-of-arel-2-0/
first, last 和 all
這三個方法可以分別拿出資料庫中的第一筆、最後一筆及全部的資料:
c1 = Category.first c2 = Category.last categories = Category.all # 這會是一個陣列
如果資料量較多,請不要在正式上線環境中執行.all 把所有資料拿出來,這樣會耗費非常多的記憶體。請用分頁或縮小查詢範圍。
find
已知資料的主鍵 ID 的值的話,可以使用 find 方法:
c3 = Category.find(1) c4 = Category.find(2)
find 也可以接受陣列參數,這樣就會一次找尋多個並回傳陣列:
arr = Category.find([1,2]) # 或是 arr = Category.find(1,2)
如果找不到資料的話,會丟 ActiveRecord::RecordNotFound 例外。如果是 find_by_id 就不會丟出例外,而是回傳 nil。
find_by_* 和 find_all_by_*
find_by_* 和 find_all_by_* 是 Rails 的動態方法,可以自由用 and 組合,例如:
c5 = Category.find_by_name('Ruby') c6 = Category.find_by_name_and_position('Ruby', 1) c7 = Category.find_all_by_position(2)
find_by_sql
如果需要手動撰寫 SQL,可以使用 find_by_sql,例如:
c8 = Category.find_by_sql("select * from categories")
不過在絕大多數的情況,是不需要手動寫 SQL 的。
where 查詢條件
where 可以非常彈性的組合出 SQL 查詢,例如:
c9 = Category.where( :name => 'Ruby', :position => 1 ) c10 = Category.where( [ "name = ? or position = ?", 'Ruby', 2] )
其中參數有兩種寫法,一種是 Hash,另一種是 Array。前者的寫法雖然比較簡潔,但是就沒辦法寫出 or 的查詢。注意到不要使用字串寫法,例如
Category.where("name = #{params[:name]}") # 請不要這樣寫
這是因為字串寫法會有 SQL injection 的安全性問題,請改用陣列寫法。
另外,where 是 lazy loading,也就是直到真的需要取值的時候,才會跟資料庫拿資料。如果需要立即觸發,可以接著使用 .all, .first, .last,例如
c11 = Category.where( :name => 'Ruby', :position => 1 ).all
limit
limit 可以限制筆數c = Category.limit(5).all c.size # 5
order
order 可以設定排序條件Category.order("position") Category.order("position DESC") Category.order("position DESC, name ASC")
如果要消去order條件,可以用
reorder:
Category.order("position").reorder("name") # 改用 name 排序 Category.order("position").reorder(nil) # 取消所有排序
offset
offset 可以設定忽略前幾筆不取出,通常用於資料分頁:c = Category.limit(2) c.first.id # 1 Category.limit(2).offset(3) c.first.id # 4
select
預設的 SQL 查詢會取出資料的所有欄位,有時候你可能不需要所有資料,為了效能我們可以只取出其中特定欄位:Category.select("id, name")
例如欄位中有 Binary 資料時,你不會希望每次都讀取出龐大的 Binary 資料佔用記憶體,而只希望在使用者要下載的時候才讀取出來。
readonly
c = Category.readonly.first
如此查詢出來的
c就無法修改或刪除,不然會丟出
ActiveRecord::ReadOnlyRecord例外。
group 和 having
(TODO)串接寫法
以上的 where, order , limit, offset, joins, select 等等,都可以自由串接起來組合出最終的 SQL 條件:c12 = Category.where( :name => 'Ruby' ).order("id desc").limit(3)
find_each 批次處理
如果資料量很大,但是又需要全部拿出來處理,可以使用 find_each 批次處理Category.where("position > 1").find_each do |category| category.do_some_thing end
預設會批次撈 1000 筆,如果需要設定可以加上 :batch_size 參數。
重新載入
如果已經讀取的 AR 資料,需要重新載入,可以用 reload 方法:p = Category.first p.reload
如何刪除
一種是先抓到該物件,然後刪除:c12 = Category.first c12.destroy
另一種是直接對類別呼叫刪除,傳入 ID 或條件:
Category.delete(2) Category.delete_all(conditions = nil) Category.destroy_all(conditions = nil)
delete 不會有 callback 回呼,destroy 有 callback 回呼。什麼是回呼詳見下一章。
統計方法
Category.count Category.average(:position) Category.maximum(:position) Category.sum(:position)
其中我們可以利用上述的 where 條件縮小範圍,例如:
Category.where( :name => "Ruby").count
如何更新
c13 = Category.first c13.update_attributes(attributes) c13.update_attributes!(attributes) c13.update_attribute(attribute_name, value)
注意 update_attribute 會略過 validation 資料驗證 注意 mass assign 安全性問題,可以透過 attr_protected 或 attr_accessor 設定。
相关文章推荐
- Ruby on Rails 入门之:(24) Ruby 中数据持久化、数据库操作
- 浅谈Ruby on Rails下的rake与数据库数据迁移操作
- Ruby on Rails数据库操作
- Ruby on Rails 数据库Migration操作语句实例
- ROR模型和数据库操作(第六章ruby on rails)
- Ruby on Rails学习心得(三)数据库基本操作
- Ruby on Rails 入门之:(16) Ruby中的定义操作、取消定义操作
- ruby on rails 的数据库查询方法
- ruby on rails 撤销取消操作
- Ruby on Rails 上传照片到数据库,在从数据库中找出发送给其他服务器
- 在Ruby On Rails项目中使用Redis做缓存数据库
- rails 操作数据库
- ruby的文件和数据库操作
- ruby操作数据库
- Ruby on Rails,rake工具使用和数据库migrations迁移的概念
- flyway框架对数据库迁徙的支持配置(基于ruby on rails的db migrate 思想)
- Ruby on rails 实战圣经:数据库迁移 - Migrations
- 在没有数据库表或者列的情况下新建model;rails ,ruby, rack
- Ruby on Rails 入门之:(23) Ruby 中文件,目录的操作
- Ruby on Rails,数据库迁移命令和迁移任务编写