天天看點

Ruby on rails ActiveRecord

ActiveRecord介紹

1.當你建立一個ActiveRecord::Base的子類,實際上是包裝一個資料庫表。

2.active record假定表名是類的複數形式。如果類名包含多個以大寫字母開頭的單詞,表名會假定以下劃線分隔這些單詞。

3.如果你不喜歡上面的做法,你可以這樣:在配置檔案中設定一個全局變量關閉它,在config目錄下environment.rb檔案中設定。

ActiveRecord::Base.pluralize_table_names=false
           

4.連接配接資料庫

active record把資料庫連接配接的概念抽象出來,有助于程式處理各種特殊資料庫的底層細節.active record程式使用通用的調用,代理了一組資料庫擴充卡的細節.

指定連接配接的一種方式是使用establish_connection()類方法。

舉例來說,

ActiveRecord::Base.establish_connection(  :adapter => "mysql",  :host => "dbserver.com",  :database => "railsdb",  :username => "railsuser",  :password => "railspw" )
           

第二種方式是:我們還可以在config/database.yml的配置檔案中設定連接配接參數。

這樣做的好處不僅在于連接配接資訊和代碼分離,而且有利于測試和部署。

5.建立新記錄

我們可以通過調用Order.new()來建立一個對象,表示orders表中的行。然後填充各屬性的值,對應表的各列。最後調用對象的save()方法存儲到資料庫。

active record的constructor可以有一個可選的塊參數。如果用上的話,這個塊會作為一個參數調用來建立一個Order。這種用法有一個好處,可以不用建立一個臨時變量。

Order.new do |o|  
o.name = "Dave Thomas"  
# . . .  
o.save 
end
           

6.讀取已經存在的行

an_order = Order.find(27) 
order_list = params[: order_ids] 
orders = Order.find(order_list) 
count = orders.size
           

find()中的有變量是指傳回比對條件的第一行,而:all傳回比對行的數組。

pos = Order.find(:all, :conditions => "name = 'dave' and pay_type = 'po'")
           

這句的意思是:傳回符合name為dave,pay_type為po的所有記錄。

pos = Order.find(:all,:conditions => "name = '#{name}' and pay_type = 'po'")
           

這句可以直接在條件中使用變量,但是這樣容易引起sql注入攻擊。

為了防止sql注入攻擊,我們可以使用動态的sql,如下:

pos = Order.find(:all,:conditions => ["name = ? and pay_type = 'po'", name])
name = params[:name] 
           

或者如下:

還有排序和 limit

find(:all,       : order => "id",       :limit => page_size,       : offset => page_num*page_size)
           

join的使用

find(:all,  :conditions => "pr.title = 'Programming Ruby'",  :joins => "as li inner join products as pr on li.product_id = pr.id")
           

find_by_sql()帶上條件,傳入一個數組,第一個元素是一個包含占位符的字元串。數組餘下的部分或是一個散列或是替代值的清單。

7.給記錄計數

c1 = Order.count 
c2 = Order.count(["name = ?", "Dave Thomas"]) 
c3 = LineItem.count_by_sql("select count(*) " +  " from line_items, orders " +  " where line_items.order_id = orders.id " +  " and orders.name = 'Dave Thomas' ") puts "Dave has #{c3} line items in #{c2} orders (#{c1} orders in all)"
           

8.動态查找器

order = Order.find_by_name("Dave Thomas") 
orders = Order.find_all_by_name("Dave Thomas") 
order = Order.find_all_by_email(params['email'])
user = User.find_by_name_and_password(name, pw) 
           

這對大多數時侯是有效的,除非你有諸如tax_and_shipping的列名

reload()基本上是在unit test中使用,其他情況很少使用

9.更新已經存在的記錄

除了save()外,active record還可以讓你直接用單一的方法調用update_attribute()改變屬性值并儲存model對象。

order.update_attributes(:name => "Barney", :email => "[email protected]")
order = Order.update(12, :name => "Barney", :email => "[email protected]")
result = Product.update_all("price = 1.1*price", "title like '%Java%'")
           

10.save()與save!()方法

如果model對象是有效的并且能夠儲存的話,save()傳回true。

如果你想在需要的地方儲存model對象,又想所有的錯誤自動得到處理的話,你就直接使用save!()吧。這個方法如果碰到對象不能儲存,就抛出一個RecordInvalid的異常。

begin  
order.save! 
rescue RecordInvalid => error  
# validation failed 
end
           

11.删除記錄

它有兩個類方法delete()和delete_all(),都是在資料庫級别上來操作。delete()方法使用一個id或一個id數組,來删除表中相應的記錄。delete_all()删除比對給定條件的記錄行,如果沒有條件就删除全部的記錄。

12.表之間的關系

active record支援三種表之間的關系:

一對一,一對多,多對多。你可以通過在model中加入聲明has_one,has_many,belongs_to,has_and_belongs_to_many

has_one聲明一個給定的類是本身類。has_one聲明和belongs_to一樣定義同一個方法集,改變active record的預設行為。除了我們在belongs_to()看到的:class_name,:foreign_key,:conditions,還可以使用:dependent和: order。:dependent選項是指子表中的記錄行不能獨立于對應的父表記錄行而單獨存在。這就意味着如果你删除了父類的記錄,而且你定義了:dependent=>true的話,active record将會自動删除子表中相關的記錄行。 : order選項,是決定記錄傳回之前怎樣排序。

has_many聲明 has_many定義了一個屬性,它就像子類集合一樣。子表用belongs_to來表明它的父類。你要把子類作為一個數組存儲,查詢特别的子類,加入新的子類。

多對多的關系 多對多的關系是對稱的關系,兩個連接配接的表都互相使用has_and_belongs_to_many來聲明它們之間的關系