Ruby on rails开发从头来(四十六)- ActiveRecord基础(SQL和Active Record)

想象一下Active Record是如何处理SQL的,我们来看看find方法的:conditions参数,调用的时候像这样:find(:all,:conditions=>…),这里的:conditions参数决定了find方法将返回哪些记录,它相当于Sql语句的where部分,例如,要获取所有的名字为Dave,pay_type为po的订单,我们这样写:

pos = Order.find(:all,:conditions => "name = 'dave' and pay_type = 'po'")

find方法将返回所有符合条件的记录,并且都已经被转换成Order类的对象,如果没有符合条件的订单,find方法将返回一个长度为零的数组。

如果你的条件是预定的,那么上面的写法就很好了,但是如果我们要指定条件中的值呢,我们这样写:

# get the limit amount from the form
name = params[:name]
# DON'T DO THIS!!!
pos = Order.find(:all,:conditions => "name = '#{name}' and pay_type = 'po'")

但是,这并不是一个好主意,因为如果你的程序要发布在网络上的话,这样给SQL注入攻击留下了方便(后面我们在关于安全的主题里会讨论SQL注入的话题),更好的办法是,动态的生成SQL(注1),让Active Record来处理它,我们可以在SQL语句中加入占位符,然后这些占位符将会在运行期被替换成指定的值,指定占位符的方法就是在SQL中使用问号,在运行时,

第一个问号将被替换为集合的第二个元素的值,以此类推,例如,我们把上面的查询重写一次:
name = params[:name]
pos = Order.find(:all,:conditions => ["name = ? and pay_type = 'po'", name])

我们也可以使用带名字的占位符,名字前带冒号,例如下面这样:

name = params[:name]
pay_type = params[:pay_type]
pos = Order.find(:all,
:conditions => ["name = :name and pay_type = :pay_type",
{:pay_type => pay_type, :name => name}])

我也可以更进一步,因为params是一个hash,我们可以让conditions部分更简单

pos = Order.find(:all,
:conditions => ["name = :name and pay_type = :pay_type", params])

不管使用哪种占位符,Active Record都会很小心地处理SQL中的引号和escape。使用动态SQL,Active Record会保护我们不受SQL注入攻击。

注1:这里的动态sql不同于oracle等数据库中所指的动态sql,其含义类似于ADO.net中不拼接sql字符串,而是传参数来防止sql注入攻击。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索sql
, 方法
, find
, name
, order
params
rails activerecord、ruby activerecord、ruby on rails、ruby on rails 教程、ruby rails,以便于您获取更多的相关知识。

时间: 2024-12-31 01:01:58

Ruby on rails开发从头来(四十六)- ActiveRecord基础(SQL和Active Record)的相关文章

Ruby on rails开发从头来(windows)(四)-第一个添删查改例子

在上一篇Ruby on rails开发从头来(windows)(三)-实现页面间的跳转中,我们创建了两个页面来进行跳转迁移,这次我们来写一个单表维护的添删查改的例子. 1.这次我们重新创建一个项目depot,按照上篇中的步骤,创建depot项目. 2.创建数据库. 你可以使用rails的命令行,通过mysql创建,先定位到depot目录,使用命令: depot> mysql -u root –p 密码为空,连接mysql后执行下面的命令: mysql> create database depo

Ruby on rails开发从头来(windows)(三)-实现页面间的跳转

在上篇随笔Ruby on rails开发从头来(windows)(二)-创建项目和第一个Hello world 中,我们介绍了如何使用InstantRails创建一个项目和编写一个简单的Helloworld页面,今天在上次的基础上,写一个简单的页面跳转. 1.将appcontrollers目录下的say_controller.rb文件的内容改成下面这样: class SayController < ApplicationController def Hello @time = Time.now

Ruby on rails开发从头来(四十三)- ActiveRecord基础(连接数据库)

Active Record抽象了数据库连接的概念,帮助应用程序来处理底层的数据库链接的细节,作为替代,Active Record使用通用的调用,将细节委托给一组数据库适配器. 可以使用establish_connection( )方法来制定连接,下面的例子创建了一个mysql数据库连接,数据库的名字是railsdb,服务器的Host名为dbserver.com,用户名为railsuser,密码为railspw. ActiveRecord::Base.establish_connection( :

Ruby on rails开发从头来(windows)(一)

使用InstantRails快速搭建Ruby On Rails开发环境 一直对Ruby on Rails抱有很大的兴趣,想看看这个被很多人称道的东西,但是一直在做windows下的开发,对于Ruby on Rails的开发环境搭建还是很头疼,这也是一直没有开始研究Ruby on rails的原因.刚刚在javaeye看到了InstantRails,一个All In One的套件,可以帮助你快速搭建Ruby On Rails开发环境,就立即下了一个试了试,还好,比较顺,起码可以跑起来自带的例子了.

Ruby on rails开发从头来(四十)- ActiveRecord基础(Boolean属性)

一些数据库支持boolean类型,而另一些则不支持,这使得Active Record要抽象boolean类型变得困难.例如,如果数据库不支持boolean类型,有的开发者使用char(1)来替代,而内容使用"t"和"f"来表示true和false,而另外一些开发者使用integer类型,0是false,1是true.即使数据库支持boolean类型,在内部也许还是使用0和1来存储. 在Ruby里,在条件判断中,数字0和字符f都被认为是true值,这就意味着如果你直接

Ruby on rails开发从头来(五十四)- ActiveRecord基础(指定关联关系)

Rails支持三种表间关联关系,一对一,一对多,多对多,你需要在Model中加入声明来标识这些关联:has_one,has_many,belongs_to,has_and_belongs_to_many. 一对一关联关系可能存在于象订单和发票这样的关系,一个订单只能有一个发票,在Rails中,我们这样指明: class Order < ActiveRecord::Base has_one :invoice . . . class Invoice < ActiveRecord::Base bel

Ruby on rails开发从头来(四十九)- ActiveRecord基础(行数和再加载数据)

Active Record提供了两个方法来获取符合条件的记录的条数:count()和count_by_sql().例如: c1 = Order.count c2 = Order.count(["name = ?", "Dave Thomas"]) c3 = LineItem.count_by_sql("select count(*) " + " from line_items, orders " + " where

Ruby on rails开发从头来(四十八)- ActiveRecord基础(动态查询)

数据库上最常运行的查询莫过于根据指定条件返回符合的结果集,查询可能是返回所有名字为'dave'的订单,或者是某个博客上所有标题含Rails的post,在很多其他的框架和程序设计语言中,你需要创建sql来执行查询,Active Record利用了ruby语言所包含的动态能力来做这些事. 例如,我们的Order Model包含了诸如name,email,address这样的属性,我们可以使用这些名字对应的find方法来查询,例如: order = Order.find_by_name("Dave T

Ruby on rails开发从头来(四十五)- ActiveRecord基础(读取记录)

读取记录包括指定那些特定的数据是你感兴趣的,你给Active Record指定标准,Active Record再返回给你一些对象,其中包含了符合条件的记录的数据. 在一个表中检索数据的最简单的办法就是指定主键,任何一个Model都支持find()方法,该方法支持一个或多个主键值,如果只指定了一个主键,将会返回对应的对象,如果指定了多个主键给find方法,该方法一组相应的对象.注意,当没有任何符合条件的数据的时候,将会抛出一个RecordNotFound异常,所以如果find方法没有抛出这个异常的