前面了解了檢索的方法,這次來看看Active Record怎樣更新數據庫中的記錄。
如果你有一個Active Record對象(或許對應於order表),你可以通過調用save方法將它寫道數據庫中去,如果這個對象是先前從數據庫中讀取出來的,save方法將會更新既有的記錄,否則將會新建一條記錄。
如果一條既有記錄被更新,Active Record將會用它的主鍵和來匹配內存中的對象,Active Record對象中的屬性被更新到對應的列,即使一個列中的值沒有變化也會被更新,在下面的例子中,id為123的訂單所有的內容都會被更新:
order = Order.find(123) order.name = "Fred" order.save
不管怎樣,在下面的例子裡,Active Record對象只包含id,name,paytype,當對象被保存的時候僅僅只有這些字段被更新,注意如果你想要把對象保存到數據庫,那麼在使用find_by_sql方法時,一定要包含id字段。
orders = Order.find_by_sql("select id, name, pay_type from orders where id=123") first = orders[0] first.name = "Wilma" first.save
另外,Active Record還提供了update_attribute()方法,該方法可以將Model對象的某個屬性保存到數據庫。
order = Order.find(123) order.update_attribute(:name, "Barney") order = Order.find(321) order.update_attributes(:name => "Barney", :email => "[email protected]")
我們可以把讀取和更新結合在一起,使用update()方法或update_all(),update()方法使用一個id和一組屬性,如果在數據庫中對應的記錄,就更新指定的屬性,然後返回model對象。
order = Order.update(12, :name => "Barney", :email => "[email protected]")
也可以傳遞一組id或者屬性和值的hash給update()方法,這樣會更新所有匹配的記錄,並且返回一組model對象。
最後,update_all()方法允許你指定給update語句指定Where條件,下面的例子給所有標題中含有java的商品漲價10%:
result = Product.update_all("price = 1.1*price", "title like '%Java%'")
這裡的返回值依賴於具體的數據庫適配器,很多數據庫都返回被更新的記錄數目。
下面我們看看save()和save!()這兩個方法。
簡單的save()方法在Model對象存在並且可以的保存的情況下返回true:
if order.save # all OK else # validation failed end
這樣會導致你在所有調用save方法的地方都要加上檢查,但是Active Record假定save方法是在Controler的Action的上下文中的,並且視圖裡的代碼不進行這些檢查。(這部分書上看不明白,不能確定)。
不管怎樣,如果你需要在上下文環境中保存Model對象,並且想確定是否所有的錯誤都被處理了,你可以使用save!()方法,如果Model對象不能保存,那麼這個方法會拋出一個RecordInvailid異常:
begin order.save! rescue RecordInvalid => error # validation failed end