Lai*_*uan 9 activerecord ruby-on-rails
例如,user
有一个list
,list
有很多item
s,我在控制器中有以下代码:
@user = User.new()
@list = List.new()
(1..10).each { |i| @list.items << (Item.new(:order => i)) }
@user.list = @list
Run Code Online (Sandbox Code Playgroud)
现在,如果我打电话@user.save
,@list
10 item
秒将不会保存到数据库.我该如何重写这段代码?
inf*_*sed 10
通过设置适当的关联和验证,您可以确保在保存用户时,同时保存关联的列表和项目.此外,您可以确保在一个事务中保存所有内容,并且如果无法保存子记录,则将中止保存.
给定User,List和Item的以下模型定义
class User < ActiveRecord::Base
belongs_to :list
validates_associated :list
end
class List < ActiveRecord::Base
has_many :items
validates_associated :items
end
class Item < ActiveRecord::Base
validates :name, presence: true
end
Run Code Online (Sandbox Code Playgroud)
调用user.save
具有无效列表项的用户现在将返回false,并且不会保存任何记录.您可以查询user.errors
以找出保存中止的原因.
user = User.new
list = user.build_list
list.items.build(name: nil)
user.save # => false
user.errors.messages # => {:list=>["is invalid"]}
user.list.error.messages # => {:items=>["is invalid"]}
Run Code Online (Sandbox Code Playgroud)
由于Item验证了名称的存在,因此项目的保存失败,并且没有保存任何记录.您在SQL日志中应该看到的内容如下:
(0.2ms) BEGIN
(0.2ms) ROLLBACK
Run Code Online (Sandbox Code Playgroud)
现在,如果所有记录都有效:
user = User.new
list = user.build_list(name: 'My List')
list.items.build(name: 'Widget')
user.save # => true
Run Code Online (Sandbox Code Playgroud)
ActiveRecord将以正确的顺序保存记录,以便设置foreign_keys.所有3个插入也包含在事务中:
(0.2ms) BEGIN
SQL (0.3ms) INSERT INTO `lists` (`name`) VALUES ('My list')
SQL (0.1ms) INSERT INTO `items` (`list_id`, `name`) VALUES (4, 'Widget')
SQL (0.3ms) INSERT INTO `users` (`list_id`) VALUES (4)
(0.3ms) COMMIT
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1148 次 |
最近记录: |