zoukankan      html  css  js  c++  java
  • Ruby on rails开发从头来(四十七) ActiveRecord基础(强大的find方法)

         现在我们知道如何指定条件,现在我们来看看find方法支持的一些其他设置。

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

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

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

    daves_orders = Order.find(:all, :conditions => "name = 'Dave'")

    name = params[:name]

    other_orders = Order.find(:all, :conditions => ["name = ?", name])

    yet_more = Order.find(:all,

    :conditions => ["name = :name and pay_type = :pay_type",

    params])

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

    orders = Order.find(:all,

    :conditions => "name = 'Dave'",

    :order => "pay_type, shipped_at DESC")

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

    orders = Order.find(:all,

    :conditions => "name = 'Dave'",

    :order => "pay_type, shipped_at DESC",

    :limit => 10)

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

    def Order.find_on_page(page_num, page_size)

    find(:all,

    :order => "id",

    :limit => page_size,

    :offset => page_num*page_size)

    end

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

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

    LineItem.find(:all,

    :conditions => "pr.title = 'Programming Ruby'",

    :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语句,下面是示例代码:

    orders = LineItem.find_by_sql("select line_items.* from line_items, orders " +

    " where order_id = orders.id " +

    " and orders.name = 'Dave Thomas' ")

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

    orders = Order.find_by_sql("select name, pay_type from orders")

    first = orders[0]

    p first.attributes

    p first.attribute_names

    p first.attribute_present?("address")

    程序的结果:

    {"name"=>"Dave Thomas", "pay_type"=>"check"}

    ["name", "pay_type"]

    false

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

    items = LineItem.find_by_sql("select *, " +

    " 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}"

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

    Order.find_by_sql(["select * from orders where amount > ?",

    params[:amount]])
  • 相关阅读:
    Code Forces Gym 100886J Sockets(二分)
    CSU 1092 Barricade
    CodeChef Mahesh and his lost array
    CodeChef Gcd Queries
    CodeChef GCD2
    CodeChef Sereja and LCM(矩阵快速幂)
    CodeChef Sereja and GCD
    CodeChef Little Elephant and Balance
    CodeChef Count Substrings
    hdu 4001 To Miss Our Children Time( sort + DP )
  • 原文地址:https://www.cnblogs.com/dahuzizyd/p/ruby_rails_study_47.html
Copyright © 2011-2022 走看看