ActiveRecord

ActiveRecord介绍


1.当你创建一个ActiveRecord::Base的子类,实际上是包装一个数据库表。
2.active record假定表名是类的复数形式。如果类名包含多个以大写字母开头的单词,表名会假定以下划线分隔这些单词。
3.如果你不喜欢上面的做法,你可以这样:在配置文件中设置一个全局变量关闭它,在config目录下environment.rb文件中设置。

 

代码:


ActiveRecord::Base.pluralize_table_names=false 
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"  ) 
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.读取已经存在的行

Java代码 复制代码
  1. an_order = Order.find(27)    
  2. order_list = params[: order_ids]    
  3. orders = Order.find(order_list)    
  4. count = orders.size  
an_order = Order.find(27) 
order_list = params[: order_ids] 
orders = Order.find(order_list) 
count = orders.size

 

#count方法总是会产生count(*)的SQL语句去查询数据库,而#length方法总是取查询出的集合的个数,它总是不会产生count(*)的查询,#size方法就比较好了,如果目标集合还没有取出来,它会像#count方法一样,产生count(*)的查询,如果记录已经取出来了,它就像#length方法一样,直接读取集合的个数了


find()中的有变量是指返回匹配条件的第一行,而:all返回匹配行的数组。

Java代码 复制代码
  1. pos = Order.find(:all, :conditions => "name = 'dave' and pay_type = 'po'")  
pos = Order.find(:all, :conditions => "name = 'dave' and pay_type = 'po'")


这句的意思是:返回符合name为dave,pay_type为po的所有记录。

Java代码 复制代码
  1. pos = Order.find(:all,:conditions => "name = '#{name}' and pay_type = 'po'")  
pos = Order.find(:all,:conditions => "name = '#{name}' and pay_type = 'po'")


这句可以直接在条件中使用变量,但是这样容易引起sql注入攻击。
为了防止sql注入攻击,我们可以使用动态的sql,如下:

Java代码 复制代码
  1. pos = Order.find(:all,:conditions => ["name = ? and pay_type = 'po'", name])   
  2. name = params[:name]   
pos = Order.find(:all,:conditions => ["name = ? and pay_type = 'po'", name])
name = params[:name] 


或者如下:

Java代码 复制代码
  1. pay_type = params[:pay_type]    
  2. name = params[:name]   
  3. pos = Order.find(:all,:conditions => ["name = :name and pay_type = :pay_type",                                 {:pay_type => pay_type, :name => name}])  
pay_type = params[:pay_type] 
name = params[:name]
pos = Order.find(:all,:conditions => ["name = :name and pay_type = :pay_type", {:pay_type => pay_type, :name => name}])


还有排序和 limit

Java代码 复制代码
  1. find(:all,        : order => "id",        :limit => page_size,        : offset => page_num*page_size)  
find(:all,       : order => "id",       :limit => page_size,       : offset => page_num*page_size)


join的使用

Java代码 复制代码
  1. find(:all,   :conditions => "pr.title = 'Programming Ruby'",   :joins => "as li inner join products as pr on li.product_id = pr.id")  
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.给记录计数

Java代码 复制代码
  1. c1 = Order.count    
  2. c2 = Order.count(["name = ?""Dave Thomas"])    
  3. 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)"  
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.动态查找器

Java代码 复制代码
  1. order = Order.find_by_name("Dave Thomas")    
  2. orders = Order.find_all_by_name("Dave Thomas")    
  3. order = Order.find_all_by_email(params['email'])   
  4. user = User.find_by_name_and_password(name, pw)   
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对象。

Java代码 复制代码
  1. order.update_attributes(:name => "Barney", :email => "barney@bedrock.com")   
  2. order = Order.update(12, :name => "Barney", :email => "barney@bedrock.com")   
  3. result = Product.update_all("price = 1.1*price""title like '%Java%'")  
order.update_attributes(:name => "Barney", :email => "barney@bedrock.com")
order = Order.update(12, :name => "Barney", :email => "barney@bedrock.com")
result = Product.update_all("price = 1.1*price", "title like '%Java%'")


10.save()与save!()方法
如果model对象是有效的并且能够保存的话,save()返回true。
如果你想在需要的地方保存model对象,又想所有的错误自动得到处理的话,你就直接使用save!()吧。这个方法如果碰到对象不能保存,就抛出一个RecordInvalid的异常。

Java代码 复制代码
  1. begin      
  2. order.save!    
  3. rescue RecordInvalid => error      
  4. # validation failed    
  5. end  
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来声明它们之间的关系

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值