转载▼
数据库元被影射成对象
(object-relational mapping (ORM)层)
class和table的命名对应关系实例:
Ruyb数据类型和SQL数据类型对应关系表:
访问属性(数据库列):
访问属性(数据库列)更方便的方法:
account.balance #=> 返回当前值
account.balance = 0.0 #=> 指定数值
以上方式得到的数据库数据将是ruby按自身的数据类型格式化好的,如果要得到原始数据,可用以下形式代码:
account.balance_before_type_cast #=> "123.4", 字符串
account.release_date_before_type_cast #=> "20050301"
是非属性
在ruby中只有false或nil才被判断为false
通常用以下代码判断:
superuser?将以下结果判断为false:
1.数字0
2.字符"0", "f", "false", 或""(空字符)
3.nil
4.常量false
自定义判断原则的方法:
数据库主键(Primary Keys)
Ruby on Rails默认以id为主键
自定义主键的方法:
class BadBook < ActiveRecord::Base
set_primary_key "isbn"
end
数据创建,读取,更新和删除(CRUD:Create, Read, Update, Delete)
创建新数据
实例:
用以下方式可以减少产生一个an_order变量:
当数据来自HTML表单时,可以考虑用以下方式:
使用create()代换new()可直接保存到数据库,省去an_order.save:
可以使用hash同时保存多组数据:
new()或create()也可以直接接参数:
order = Order.create(params)
读取数据
不安全的表单参数传递读取数据库:
更安全的方法:
你也可以这样:
终极简化版:
排序和查找第3(?)至13(?)列的方法:
联合数据表的查找方法(一般用不上):
查找有序一列的方法:
直接使用sql语句的查询方法:
在这里你也可以传递参数:
计算行数
动态查询
可同时查多个条件,如:
重载数据库
更新数据
使用save()
使用update_attribute()
使用更快捷的update()
使用update_all()
数据锁(防止数据保存撞车)
加段:lock_version int default 0,
删除数据
destroy()冻结(在model层面)
(object-relational mapping (ORM)层)
Ruby代码
- table<=>class
- row<=>object
- column<=>object
attribute
class和table的命名对应关系实例:
Ruby代码
- Order<=>orders
- TaxAgency<=>tax_agencies
- Person<=>people
Ruby代码
- #复数形式关闭方法config/environment.rb:
- ActiveRecord::Base.pluralize_table_names
= false - #自定义表格名称方法:
- class
Sheep < ActiveRecord::Base - set_table_name
"sheep" - end
Ruyb数据类型和SQL数据类型对应关系表:
Ruby代码
- int,integer<=>Fixnum
- float,double,decimal,numeric<=>Float
- interval,date<=>Date
- datetime,time<=>Time
- char,varchar,string,clob,blob,text<=>String
- boolean<=>see
text...
访问属性(数据库列):
Ruby代码
- account[:balance]
#=> 返回当前值 - account[:balance]
= #=>0.0 指定数值
Ruby代码
- #修正数据库列的取值范围的方法:
- class
Account < ActiveRecord::Base - def
balance=(value) -
BalanceTooLow ifvalue < MINIMUM_LEVEL -
= value - end
- end
访问属性(数据库列)更方便的方法:
account.balance #=> 返回当前值
account.balance = 0.0 #=> 指定数值
以上方式得到的数据库数据将是ruby按自身的数据类型格式化好的,如果要得到原始数据,可用以下形式代码:
account.balance_before_type_cast #=> "123.4", 字符串
account.release_date_before_type_cast #=> "20050301"
是非属性
在ruby中只有false或nil才被判断为false
通常用以下代码判断:
Ruby代码
- user
= "Dave")Users.find_by_name( - if
user.superuser? - grant_privileges
- end
superuser?将以下结果判断为false:
1.数字0
2.字符"0", "f", "false", 或""(空字符)
3.nil
4.常量false
自定义判断原则的方法:
Ruby代码
- class
User < ActiveRecord::Base - def
superuser? -
== 'J' - end
- #
. . . - end
数据库主键(Primary Keys)
Ruby on Rails默认以id为主键
自定义主键的方法:
class BadBook < ActiveRecord::Base
set_primary_key "isbn"
end
数据创建,读取,更新和删除(CRUD:Create, Read, Update, Delete)
创建新数据
实例:
Ruby代码
- an_order
= newOrder. - an_order.name
= "DaveThomas" - an_order.email
= "dave@pragprog.com" - an_order.address
= "123Main St" - an_order.pay_type
= "check" - an_order.save
#在save()之前所有数据只存在内存中
用以下方式可以减少产生一个an_order变量:
Ruby代码
- Order.new
do |o| - o.name
= "DaveThomas" - #
. . . - o.save
- end
当数据来自HTML表单时,可以考虑用以下方式:
Ruby代码
- an_order
= new(Order. - :name
=> "DaveThomas" , - :email
=> "dave@pragprog.com", - :address
=> "123Main ,St" - :pay_type
=> "check") - an_order.save
使用create()代换new()可直接保存到数据库,省去an_order.save:
Ruby代码
- an_order
= Order.create( - :name
=> "DaveThomas" , - :email
=> "dave@pragprog.com", - :address
=> "123Main ,St" - :pay_type
=> "check")
可以使用hash同时保存多组数据:
Ruby代码
- orders
= Order.create( -
[ { => "DaveThomas" , -
=> "dave@pragprog.com", -
=> "123Main ,St" -
=> "check" -
}, -
{ => "AndyHunt" , -
=> "andy@pragprog.com", -
=> "456Gentle ,Drive" -
=> "po" -
} ] )
new()或create()也可以直接接参数:
order = Order.create(params)
读取数据
Ruby代码
- an_order
= #Order.find(27) 直接找出id = 27的数据 - #
从一个表单读取product id列表,然后计算这些商品的总价: - product_list
= :product_ids]params[ - total
= 0.0 - Product.find(product_list).each
{|prd| total += prd.total}
Ruby代码
- 带条件的读取:
- pos
= :all,Order.find( - :conditions
=> "name= )'dave' and pay_type = 'po'"
不安全的表单参数传递读取数据库:
Ruby代码
- name
= :name]params[ - #
此方法有被SQL注入方式入侵的风险!!! - pos
= :all,Order.find( - :conditions
=> "name= )'#{name}' and pay_type = 'po'" - #注意上面单双引号的使用及变量的传递方法
更安全的方法:
Ruby代码
- name
= :name]params[ - pos
= :all,Order.find( - :conditions
=> "name[ = ,? and pay_type = 'po'" name])
你也可以这样:
Ruby代码
- name
= :name]params[ - pay_type
= :pay_type]params[ - pos
= :all,Order.find( - :conditions
=> "name[ = ,:name and pay_type = :pay_type" - {
:pay_type
=> :namepay_type, => name}])
终极简化版:
Ruby代码
- pos
= :all,Order.find( - :conditions
=> "name[ = ,:name and pay_type = :pay_type" params])
排序和查找第3(?)至13(?)列的方法:
Ruby代码
- orders
= :all,Order.find( - :conditions
=> "name= ,'Dave'" - :order
=> "pay_type,shipped_at ,DESC" - :limit
=> 10 - :offset
=> 2)
联合数据表的查找方法(一般用不上):
Ruby代码
- LineItem.find(:all,
- :conditions
=> "pr.title= ,'Programming Ruby'" - :joins
=> "asli )inner join products as pr on li.product_id = pr.id"
查找有序一列的方法:
Ruby代码
- order
= :first,Order.find( - :conditions
=> "name= ,'Dave Thomas'" - :order
=> "idDESC" )
直接使用sql语句的查询方法:
Ruby代码
- items
= "selectLineItem.find_by_sql( *, )quantity*unit_price as total_price,products.title as title from line_items, products where line_items.product_id = products.id " - li
= items[0] - puts
"#{li.title}: #{li.quantity}x#{li.unit_price} => #{li.total_price}" - #你可以使用"as".
在这里你也可以传递参数:
Ruby代码
- Order.find_by_sql(["select
* ,from orders where amount > ?" - params[:amount]])
计算行数
Ruby代码
- c1
= Order.count - c2
= "nameOrder.count([ = ,?" "Dave Thomas" ]) - c3
= "selectLineItem.count_by_sql( count(*) )from line_items, orders where line_items.order_id = orders.id and orders.name = 'Dave Thomas' " - puts
"Dave在#{c2}个定单里一共定了#{c3} 件商品 (目前定单总数:#{c1})"
动态查询
Ruby代码
- order
= "DaveOrder.find_by_name( Thomas" )#只查一列 - orders
= "DaveOrder.find_all_by_name( Thomas" ) - order
= 'email'])Order.find_all_by_email(params[
可同时查多个条件,如:
Ruby代码
- user
= User.find_by_name_and_password(name, pw)
重载数据库
Ruby代码
- stock
= "RUBY")Market.find_by_ticker( - loop
do - puts
"Price = #{stock.price}" - sleep
60 - stock.reload
- end
更新数据
使用save()
Ruby代码
- order
= Order.find(123) - order.name
= "Fred" - order.save
-
- orders
= "selectOrder.find_by_sql( id, )name, pay_type from orders where id=123" - first
= orders[0] - first.name
= "Wilma" - first.save
使用update_attribute()
Ruby代码
- order
= Order.find(123) - order.update_attribute(:name,"Barney")
- order
= Order.find(321) - order.update_attributes(:name
=> "Barney", - :email
=> "barney@bedrock.com")
使用更快捷的update()
Ruby代码
- order
= :nameOrder.update(12, => "Barney",:email => "barney@bedrock.com")
使用update_all()
Ruby代码
- result
= "priceProduct.update_all( = ,1.1*price" "title like )'%ruby%'"
Ruby代码
- save()和save!()
- save()
- if
order.save - #
成功 - else
- #
保存失败则... - end
Ruby代码
- save!()
- begin
- order.save!
- rescue
RecordInvalid => error - #
保存失败RecordInvalid exception - end
数据锁(防止数据保存撞车)
加段:lock_version int default 0,
删除数据
Ruby代码
- delete()删除
- Order.delete(123)
- User.delete([2,3,4,5])
- Product.delete_all(["price
> ,?" @expensive_price])
destroy()冻结(在model层面)
Ruby代码
- order
= "Dave")Order.find_by_name( - order.destroy
- #
... order将被冻结