Rake 任务中的事务
我正在尝试创建一个具有事务支持的 rake 任务。 User->Profile 和 User->Location 之间存在 has_one 关系。
以下代码应该会失败,因为已经有一个用户名为“foo”的用户:
ActiveRecord::Base.transaction do
begin
u = User.create!(:username => 'foo', :email_address => '[email protected]')
p = Profile.create!(:first_name => 'foo', :last_name => 'bar')
u.profile=p
l = Location.create!(:address => "chanhassen,MN")
u.location=l
rescue Exception => e
rollback()
puts "error: #{e}"
end
end # transaction
不幸的是,不会引发错误消息(关于重复条目),并且会创建配置文件和位置模型,但不会分配给用户。我不明白什么?
--edit--
我使用了 create!() 方法而不是 create() 方法。这成功地引发了重复用户名错误。但是,如果用户验证通过,但配置文件验证失败(例如缺少last_name 字段),则仍会在数据库中创建用户。这应该会导致事务失败(确实如此)并回滚用户(不会)。
另一个问题: User.create 不会生成 id:
#<User id: nil, username: "foo">
而 Profile.create 和 Location.create 会生成:
#<Location id: 1, locatable_id: nil, locatable_type: nil>
#<Profile id: 1, user_id: nil, first_name: "foo", last_name: "bar">
似乎所有三个模型都应该等待创建主键,直到所有验证都成功。这与 has_one 关系有关吗?
I am trying to create a rake task with transaction support. There is a has_one relationship between User->Profile and User->Location.
The following code should fail, as there is already a User with the username of 'foo':
ActiveRecord::Base.transaction do
begin
u = User.create!(:username => 'foo', :email_address => '[email protected]')
p = Profile.create!(:first_name => 'foo', :last_name => 'bar')
u.profile=p
l = Location.create!(:address => "chanhassen,MN")
u.location=l
rescue Exception => e
rollback()
puts "error: #{e}"
end
end # transaction
Unfortunately, the error message (about the duplicate entry) isn't raised, and the Profile and Location models are created, but not assigned to the User. What am I not understanding?
--edit--
I used the create!() method instead of the create() method. This succeeds in raising the duplicate username error. However, if the User validation passes, but the Profile validation fails (e.g. the last_name field is missing), the User is still created in the DB. This should cause the transaction to fail (it does) and rollback the User (it doesn't).
Another question: the User.create doesn't generate an id:
#<User id: nil, username: "foo">
while the Profile.create and Location.create do:
#<Location id: 1, locatable_id: nil, locatable_type: nil>
#<Profile id: 1, user_id: nil, first_name: "foo", last_name: "bar">
Seems like all three models should wait to create their primary key until all of the validations have succeeded. Is this related to the has_one relationship?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试使用
create!
方法而不是create
(如User.create! :username => 'foo'
)。create
不会在错误时引发异常,create!
会引发异常。Try using
create!
method instead ofcreate
(as inUser.create! :username => 'foo'
).create
doesn't raise an exception on error,create!
does that.这具有所需的行为:
new() 方法不会(看起来)触发验证。 save!() 方法可以。
This has the desired behavior:
The new() method doesn't (it seems) trigger validation. The save!() method does.