find方法详解

    首先,理解find(:first,…)方法是非常重要的,该方法在同样的conditions设置下,和find(:all,…)方法生成同样的sql语句,不同之处仅在于只返回一条记录。在调用的时候,一种的参数为:first,另一种为:all。

    find方法执行一个select from这样的sql语句,:all标记指定返回表中所有的记录,:first返回第一条记录。但是现在:first还不能保证你得到的就是表中的第一条记录,原因是什么?我们继续往下看。

:conditions参数指定了SQL语句的where部分,可以包含Sql语句或者包含可以替换的参数的名字,值,上一篇我们已经做了了解。

   

Ruby代码  
  1. daves_orders = Order.find(:all:conditions => "name = 'Dave'")  
  2.   
  3. name = params[:name]  
  4.   
  5. other_orders = Order.find(:all:conditions => ["name = ?", name])  
  6.   
  7. yet_more = Order.find(:all,  
  8.   
  9. :conditions => ["name = :name and pay_type = :pay_type",  
  10.   
  11. params])  

   

   上面的find方法并不能保证按照特定的顺序返回记录,除非指定查询的排序(order by)部分。:order参数就是用来指定SQL的排序条件的,下面的例子演示了查询名字为Dave的订单,并且按照pay_type,shipped_at字段进行降序排列。

 

Ruby代码  
  1. orders = Order.find(:all,  
  2.   
  3. :conditions => "name = 'Dave'",  
  4.   
  5. :order => "pay_type, shipped_at DESC")  

 

    我们还可以设置:limit参数来限制返回的记录数,如果你使用:limit参数,或许还想指定排序条件,下面的例子返回10条记录,并且按照指定条件排序:

   

Ruby代码  
  1. orders = Order.find(:all,  
  2.   
  3. :conditions => "name = 'Dave'",  
  4.   
  5. :order => "pay_type, shipped_at DESC",  
  6.   
  7. :limit => 10)  

 
   参数:offset经常与:limit参数一同出现,用来指定从第一条记录起,返回指定的偏移量,下面代码演示了:offset参数的使用:

 

Ruby代码  
  1. def Order.find_on_page(page_num, page_size)  
  2.   
  3. find(:all,  
  4.   
  5. :order => "id",  
  6.   
  7. :limit => page_size,  
  8.   
  9. :offset => page_num*page_size)  
  10.   
  11. end  

 
     从上面的代码可以看到,这样使用find的场景就是分页显示数据,用pagesize指定每页的记录数,然后由pagenum*page_size指定从第几条开始提取数据。

参数:join用来指定主表和哪些表进行关联查询,:join参数指定的部分会插入到SQL中,下面的代码演示取得一个所有名为“Programing Ruby”的条目的列表:

 

Ruby代码  
  1. LineItem.find(:all,  
  2.   
  3. :conditions => "pr.title = 'Programming Ruby'",  
  4.   
  5. :joins => "as li inner join products as pr on li.product_id = pr.id")  

 

    在后面的内容里,我们还会了解更多的进行表关联查询的方法。

现在,我们在来回头看看:all和:first参数,实际上在使用:first参数时,默认的带有参数:limit,只不过:limit参数的值为1。如果你要取得最后一条记录,只需要改变:order里的排序方向为降序。

 

find方法为我们构建了完整的Sql查询,而方法find_by_sql方法则允许我们对Sql有完整的控制,该方法只有一个参数,就是你想要使用的完整的sql语句,下面是示例代码:

 

Ruby代码  
  1. orders = LineItem.find_by_sql("select line_items.* from line_items, orders " +  
  2.   
  3. " where order_id = orders.id " +  
  4.   
  5. " and orders.name = 'Dave Thomas' ")  

 

     现在有一个问题了,就是返回的Model对象中都包含有哪些属性呢?我们使用attributes( ), attribute_names( ), and attribute_present?( )方法来确定在Model对象中都包含有哪些属性,第一个返回一个hash,里面是键值对,第二个返回属性名的数组,第三个判断Model对象中是否含有某个属性,例如:

 

 

Ruby代码  
  1. orders = Order.find_by_sql("select name, pay_type from orders")  
  2.   
  3. first = orders[0]  
  4.   
  5. p first.attributes  
  6.   
  7. p first.attribute_names  
  8.   
  9. p first.attribute_present?("address")  
  10.   
  11. 程序的结果:  
  12.   
  13. {"name"=>"Dave Thomas""pay_type"=>"check"}  
  14.   
  15. ["name""pay_type"]  
  16.   
  17. false  

 

 

    find_by_sql方法也可以用来创建包含有派生(derived)(注1)的Model对象,如果你使用了as XXX 这样的sql来给派生字段一个别名,这个别名会作为Model中的属性名,例如:

 

Ruby代码  
  1. items = LineItem.find_by_sql("select *, " +  
  2.   
  3. " quantity*unit_price as total_price, " +  
  4.   
  5. " products.title as title " +  
  6.   
  7. " from line_items, products " +  
  8.   
  9. " where line_items.product_id = products.id ")  
  10.   
  11. li = items[0]  
  12.   
  13. puts "#{li.title}: #{li.quantity}x#{li.unit_price} => #{li.total_price}"  

 

在find_by_sql方法中,我们一样可以使用占位符来给Sql语句传递参数,例如:

 

Ruby代码  
  1. Order.find_by_sql(["select * from orders where amount > ?",  
  2.   
  3. params[:amount]])   

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值