开发工具:
文件大小: 540kb
下载次数: 0
上传时间: 2019-03-17
详细说明:
NULL
博文链接:https://thinking80s.iteye.com/blog/411613chapter
Activerecord
NEW OPTIONS FOR ASSOCATIONS VALIDATE
新的rals添加了一个新的选项到关联里面。 validate项可以用来设置是否验讧一个modl的关联对象。
例如
class AuditLog ActiveRecord: Base
ongs_to: developer, vaLidat
Log AuditLog create(: developer-id =>0,: message=>")
Log developer Developernew
puts log developer. vaLid?
t => false
puts log. valid?
#=> true
puts log. save
#=> true
正如你在这个例子所看到的,即使被关联的对象( Developer),无效,主对象( AuditLog)还是会被保存
到数据库。这个早前的 Jrails版本里面是不可用的,之前只有所有的子对象都有效的情况下,父对象才能被
保存。
虽然我在前面的例子用了验证来展示这个特性,在rais2.2默认设置里 validate缺省值就是 false,所以在
上面 validate=> falsc实际上并不需要。另外,如果你想使用之前版本的效果,就必须使用 validate=>tue
NEW WAY OF SPECIFYING CONDITIONS WITHA HASH
当执行数据库查询时,有时你需要使用join选项,或者在程序里面根据另一个表査询的结果来获得所需要
的信息。
例如,如果你要得到所有买个红色tems的用户,你可能会这样做:
User. all joins => items,: conditions =>L items. color =?,red]
这样的语法有点奇怪,因为你必须使用表的名字( items)在宇符里面。
在ri2,2里面有新的做法,用一个 hash kev来标记这个表
User.all joins => items,: conditions =>i: age=>10,: items =>i: color =>red
4这个例子可能看起来更清楚一点
user.all: Joins=>: utems,: conditi。ns→>{
: users→>{
age→18
items =>i: color = red"y
在我看来,这段代码看起来更清楚,特别当你需发为多个表的多个项提供条件。如果你指定一个查询,
要记住那个key是表的名字(复数)或者其他別名
NEW FROM OPTION FOR CALCULATION METHODS IN ACTIVERECORD
在 ActivcRccord的计算方法( count;um, avcragc, minimum, maxium)里包括了一个新的选项。
当你使用:from诜项时,你可以在 ActiveRecord产生的查询里覆盖表的名字,虽然咋一看没什么用,但它
允许你强制 MYSQL使用索引来计算。
看一下这个例子
Forcing My SQL to use an index for a calculation
Edge count :alL,: from=>edges USE INDEX(unique_edge_index)
conditions =>sink_id< 5
#f doing the calculation in a different table from the associated class
Company. count all,: from=>accounts
THE MERGE CONDITIONS METHOD N ACTIVERECORD IS NOW PUBLIC
Actiyerecord的 merge conditions方法现在是一个公有的方法,你现在可以在你的 models里面使用这个方
这个方法的作用和它的名字一样,它可以让你在参数里面提供很多不同的条件来合并为一个条件
class post activerecord : base
a =t: author = Carlos brando
b=['title=?, 'Edge rails
Post, merge_conditions (a, b
# =>"(\"posts\"\"author\"=Carlos brando) ANd (title = 'Edge rails)
注意这些条件大部分通过AND结合。
DEFINING HOW VALIDATES LENGTH OF SHOULD FUNCTION
validates length o是 Acliverecord众多验证方法之一。这个特殊的方法可以保证保存在数据库甲面的值有
指定的长度。你可以指定一个最大值,一个最小值,一个确切的值,或老一个范围。
“长度”,是相对的。当我们说到长度时大部分情况是指文本字符的个数。但一个情况就是用户要提交
篇短文,表单项它限定的不是字符的个数,而是单词的个数,像 Write a paragraph with at least100
wods《我认为 Submit a comment with no more than100 words更好一点。)
在 rails2.2之前,唯一个小法就是创建一个自定义的验证方法,现在你可能添加: tokenizer到
validates length of里面设置。下面的例子解决了上述的问题
validates_ length_of essay
minimum = 100
too_short =>"Sua redacao deve ter no minimo %d palavras. "
tokenizer=> lambda ilstr I str scan(/\w+)]
这只是一个使用该新选项的例子。你还可以用它来数位的个数,一个单词出现的个数,等等。
TREATING THE LIMIT OPTION AS COLUMIN BYTE SIZE
在新版本 rails里,ini可以在为 MySQL和 PostgreSQL的整数列里指定字节的个数(Sqie也可以了)
该列的类型依赖于指定的字节个数。看一下在MySL里决定列类型的代码段,
when 1; tinyint
when 2:' smallint
when 3: ' mediumint
when nil, 4, 11; 'int(11)'# compatibility with MySQL default 2
when 5.. 8:bigint
else raise(ActiveRecordError,"No integer type has byte size #ilimit]")
PostgreSQL
When 1.2:' ' smallint
when.4, nil; integer
when 5.. 8; bigint
NDICATING ANOTHER PRIMARY KEY IN ASSOCIATIONS
在 has many和 has onc方法里添加了一个新的选项叫 primary kcy
用这个选项,你可以定义在关联里面返回仆么样的方法和关联的 model来返回主键。显然标准的主键是id.
看卜这个用法的例子
has_many clients_using_primary-key,: class_name =>Client
primary-key =>name,: foreign_key =>'firm_name
has one和上面解釋的使用方法一样。
NEW TEST HELPER (ASSERT- SQL)
你可能听说过 assert queries,它可以用来验证测试和数据库查询执行次数。例如:
在下面的测试里我指定了如果有部分更新,会有在数据库里执行一个查询语句,否则不会有查询语句被
执行。
现在我们有了一个新的 helper可以更方便地测试sq查询。例如
def test_empty_with_counter_sql
company= Firm. find(: first)
assert_Sql /coUnt/i do
assert_equaL false, company clients. empty?
d
在上面的例子里我在一个指定的 block里面执行断言,至少一个查询会包活 COUNT
你可以在正则表达式里面指定很多东西。看一下另一个例子
assert_SqL(/(\"companies".\"id\"In \(1\)\)/) do
Account. find (1, include => firm)
MIGRATIONPROXY
想像一下,运行完很多 migrations后,一个 model的名字被改掉了。在它改变之前有其他的 migration会关联
到这个mode种情况会抛出一个错误并且停止 migrations的执行,因来所有的 migrations都会被加载不管
它们是否会被执行。
为了避免这种间题,新创建了一个 Migration Proxy新类,它保存了每个 migration的名字,版本和文件名,
在需要的时候会用这些信息来加载 migrations,这个它们不会在同一个时间加载进来。
CONNECTION POOLS IN RAILS
经常会有很多人抱怨 rails大慢了。这不是完全准确的,但是我们知道有很多方法可以提高 rails的执行效
率
已经有东西增加了 rails的性能,那就是数据库连接池
纣一次创建一个数据库査询吋,有候会在获得数据或者保存之前能创建个新的数据库连接。看起
来很重要,但是创建一个数据库连接不是那么简单。必须打开一个网络连接到数据库服务器,要验证很
多东西。所有的这些都会消耗资源和时间。创建完连接之后,rais用它来执行所有的可用的数据库请求
人的请求会延迟其佃的请求的执行。这就说明很多情况下数据库会拖大型rail项目的后腿
解决这个问题的方法就是重用之前凵经创建的数据库连接,让它们关闭之前执行更多的任务。用技术的
词语就是需要一个数据库连接池
是这样做的:只有一个数据库连接打开了,查询才能被执行。之前,我们并不关闭它,而是把它保存
在一个数据库连接池生自。当其他的请求被执行时,系统直接从连接池里面取出一个连接来执行这个数
据库操作,而不是创建一个新的迕接,这样可以減少时间和资源的消耗。在同一时间,很多个迕接保存
在连接池里,请求会自动分发给它们。这意味着一^慢的查询执行的同吋,程序依然可以获取请求,用
池里面的其他连接执行查询。
在rail里,每次执行 establish connection方法时会创建一个新的连接池。换句活说,每个在 database. ym里
血的数据库有一个属于它自己的连接泡。
连接池一丌始是空的然后一直增加直到达到缺省5个连接的限制,但是你可以在数据库配置里增加这个
缺省值。
deve lopment
adapter: mysqL
host: localhost
username: myuser
password: mypass
database: somedatabase
pool: 10
lait timeout: 15
如果没有连接可用,一个线程会在超时之前等待另一个连妄5秒。这个等待周期也可以在数据库配置里面
配置,配置诜项是 wait timeout
你自己操作池里连接的保持和释放。别忘记在使用完一个连接后释放它以便让其他请求多oo,它可以让
如果你想要在 Action pack外面使用数据车连接池,可以调用 Active record:Base. connection
connection= ActiveRecord: Base connection_pool. checkout
do something in the database
ActiveRecord: Base connection_pool. checkin(connection)
你也可以使用 Activcrccord: Basc connection pool with connection方法,它会自动为你保持和释放
ActiveRecord: Base connection_pooL with_connection do I connection I
do something in the database
end
TRANSACTIONAL MIGRATIONS IN POSTGRESQL
当一个 migration执行完,且出现了错误,只有在错误出现之前的代码提交到了数据库里。但是 migration会
被标记为完成。要修复它是很头痛的事情
但是如果你使用的数据库在事务里支持 DDL rollbacks,就有可能使用这个特性来撒消在错误发生前所有
支持的支持。
Rails已经在所有支持的数据库中添加了在 migrations里使用事务。即使Rail支持这个特性,数据库库适配
器必须被更新来文持(简单地在 supports ddl transactions?方法返回true).到这本书发布,只有 Postgre SQL
的适配器更新。
NEW DESTRUCTIVE VERSIONS OF ACTIVERECORD FIND METHODS
ActivcRccord动态查询当结果为空时为抛出一个 Rccordnotfound异常,现在会返回ni
要使用抛出昇常的版本,只妻在方法后面加一个感叹号就行∫。例如:
Topic. find_by -title! The first Topic! "
#=> ActiveRecord:: RecordNot Found
MPROVING PERFORMANCE IN ASSOCIATION D METHODS
如果你有两个 models,Pos和 Commen,个post有很多( has many) omments,如果你像卜面这样执行
Post first comment ids
Rail会使用下面的查询来获得所有的ids:
SELECT FROM comments WHERE C comments. post_id=1)
在这个情况,我们不需要返冋整个的对象。下面的查询对这个函数来说会更有效率:
SELECT comments. id FROM comments WHERE C comments. post__id= 1)
对 has many和 has many: through关联, Rails代码都更新到了这个效率更高的版本。
ANOTHER DYNAMIC FINDER
新版本添加了 find last by方法到己有的 ActiveRecord查找。另外还有 find by和 Ifind all by
除了更简便之外,这也提供了一个更优雅的方式来获得一个用户的最后的 comment例如
Comment. find_last_by_author "Carlos brando")
f is the same as
Comment last(: conditions =>i: author =>Carlos brando"s
SUPPORT FOR THE B LIMIT OPTIONN UPDATE ALL
update all方法有了一个新的imi选项。它可以保证所有使用lmit的 has many关联依然可用当你使用
updale al的吋候。
NEW OPTIONS FOR THE COMIPOSED OF METHOD
composed of方法有两个选项: constructor和: converter
constructor选项可以接受一个代表方法的标量或者一个Proc默认的情况下,组合的类是用新的方法来创建
的,获取所有相对映射的属性作为参效,特别是它们会依据映射的顺序。如果你的类不这样做的话,你
应该使用: contructor选项。不允许你改变你类创建的方式。看一下这个从 rails文档里的例子
composed_of ip_address
class name => 'IPAddr
: mapping=>‰(ipto_i)
constructor = Proc new i lipl IPAddr. new(ip, Socket: AF_INET)]
从这个例子里要以看出来,上面创建了 IPAddr类的实例,必须提供一个参数给这个 constructor.
用: constuctor让这个做法更简单。
至」: converter项,它也可以接受一个代表个方法标量,或者个Proc,当组合项从另一个实例分配和
需要转换时它会被调用。下面是一个例了
composed_of balance
class_name =>"Money
mapping→>‰N( balance amount),
:converter=> Proc. newi Balance I money. parse (balance)j
在这个例子里, balance=方法会期望获得一个 Money类的实例,但是,如果另一个类型的对象传进来,它
可以用 Money对象的 parse)法来转换。
你应该用新的: converter选项来代替该方法过去使用的 conversion block
UPDATING AN ASSOCIATION USING TS FOREIGN KEY
我不确定这是不是一个BUG,在我看来,这个已经成为一个问题了。看一下下面我在使用 rails21或者更
早版本的项目里的代码,当我想要修改一个 user's account的时候用它的外键。
class user< activerecord : Base
be longs to: account
user User. first
#=>#
user, account
#=>#
user, account id= 2
user, account
#=>#
可以看到我修改了 users account,但是关联并没有更新。即使是保存user对象之后,如果它没有重新加载,
关联依然会显示错误的 account
这个问题在 Rails22里面被修复∫。看一下
class comment active Record Base
be longs _to: post
comment Comment. first
#f = #
>>comment. post
f = #
>comment. post_id=2
>>comment. post
#=> #
注意到,用外键修改post后,关联也公自动更新。
ALIAS_ATTRIBUTE WORKS WITH DIRTY OBJECTS
要理解这个改变,我们会分析可以运行在之前和2.2版本的rais的一段代码。看一下一个 model例子
cLass comment actiyerecord : base
alias_attribute text,: body
注意到我使用 alias attribute方法来创建一个叫text的body属性的别名。理论上,这个方法应该复制所有
Active record给body属性创建的所有方法。但是所一下运行在rail2.1或更早前的代码
c= Comment. first
#=>#
C body
#=>my comment
c. text
#=>my comment
C body =a new message
#→>" a new message
C body_changed?
#t = true
C text_changed
#= NoMethodError: undefined method text_changed?
上面运行 text changed?方法时,会有错误,因来 alias attribute没有复制所有的方法,在新版本里这个问
题巳经解决了。看一卜运行在 rails22项目里的例子:
C= Comment. first
→>#< opment id:1,bo小y:" my comment">
c body
#=>my comment
c text
=>my comment
Cbody ="a new message
(系统自动生成,下载前可以参看下载内容)
下载文件列表
相关说明
- 本站资源为会员上传分享交流与学习,如有侵犯您的权益,请联系我们删除.
- 本站是交换下载平台,提供交流渠道,下载内容来自于网络,除下载问题外,其它问题请自行百度。
- 本站已设置防盗链,请勿用迅雷、QQ旋风等多线程下载软件下载资源,下载后用WinRAR最新版进行解压.
- 如果您发现内容无法下载,请稍后再次尝试;或者到消费记录里找到下载记录反馈给我们.
- 下载后发现下载的内容跟说明不相乎,请到消费记录里找到下载记录反馈给我们,经确认后退回积分.
- 如下载前有疑问,可以通过点击"提供者"的名字,查看对方的联系方式,联系对方咨询.