何时保存has_many关系中的Active Record对象?
我正在使用Rails 1.2.3(是的,我知道)并且对于has_many
如何在对象持久性方面起作用感到困惑。
为了举例,我将使用它作为我的声明:
class User < ActiveRecord::Base has_many :assignments end class Assignment < ActiveRecord::Base belongs_to :user end
根据我的理解,这会生成一个方法User#assignments.build
,它创建一个Assignment
对象,其user_id
是接收实例的id
(并且其他字段在参数中指定),但不保存此对象在数据库中。 稍后可以通过调用Assignment#save!
保存该对象Assignment#save!
。
然而,我一直在使用作为教程和参考的实用程序员使用Rails的敏捷Web开发,第二版 ,说:
如果父对象存在于数据库中,则将子对象添加到集合会自动保存该子对象。
这里似乎有矛盾。 我想知道的是:
- 如果我执行
some_user.assignments.build
,是否保存了Assignment
对象? - 如果我执行
some_user.assignments << Assignment.new
,是否保存了Assignment
对象? - 如果我做
some_user.assignments << Assignment.create
,是两个数据库调用,还是只有一个? 如果我在创建它之间修改Assignment
对象并将其添加到some_user.assignments
呢? - 如果我
save!
会怎么样save!
一个Assignment
对象,其对应的User
尚未保存在数据库中?
PS我之所以不仅仅使用User#assignments.create
的原因是因为它不允许我将初始化扩展到外部方法,我希望能够做到这一点。 我也不想多次去数据库。
注意:下面的所有控制台测试都在Rails 3中运行。您可能在Rails 1中获得不同的输出,您必须自己运行测试以进行比较。
如果您想了解使用Active Record在幕后发生的事情,那么使用rails控制台非常有价值。 以下是未保存对象的情况:
u = User.new # u.assignments.build(:name => "example") # u.save #SQL (0.2ms) INSERT INTO `users` (`created_at`, `name`, `updated_at`) VALUES ('2012-06-01 19:25:45', NULL, '2012-06-01 19:25:45') #SQL (0.2ms) INSERT INTO `assignments` (`created_at`, `name`, `updated_at`, `user_id`) VALUES ('2012-06-01 19:25:45', 'example', '2012-06-01 19:25:45', 1)
如您所见,两者都是在保存新用户的同时保存的。 现在让我们尝试场景二:
u = User.create!(:name => "test") #SQL (0.2ms) INSERT INTO `users` (`created_at`, `name`, `updated_at`) VALUES ('2012-06-01 19:27:21', 'test', '2012-06-01 19:27:21') # u.assignments.build(:name => "example") #
因此,我们可以得出结论:
如果我执行some_user.assignments.build,是否保存了Assignment对象?
不
如果我执行some_user.assignments << Assignment.new,是否保存了Assignment对象?
不。这正是assignments.build所做的,没有区别。
如果我做some_user.assignments << Assignment.create,是两个数据库调用,还是只有一个?
只是作业。
如果我在创建它之间修改Assignment对象并将其添加到some_user.assignments呢?
不明白,抱歉。
如果我保存会怎么样! 一个Assignment对象,其对应的User尚未保存在数据库中?
它在没有user_id的情况下保存到数据库中。 然后,当您为用户调用save时,会向该分配发出更新命令以添加用户ID。 这是在控制台:
u = User.new(:name => "John Doe") # a = Assignment.new(:name => "test") # u.assignments << a #[# ] a.save! #SQL (0.2ms) INSERT INTO `assignments` (`created_at`, `name`, `updated_at`, `user_id`) VALUES ('2012-06-01 19:33:24', 'test', '2012-06-01 19:33:24', NULL) a.user_id #nil u.save! #INSERT INTO `users` (`created_at`, `name`, `updated_at`) VALUES ('2012-06-01 19:33:36', 'John Doe', '2012-06-01 19:33:36') #UPDATE `assignments` SET `user_id` = 3, `updated_at` = '2012-06-01 19:33:36' WHERE `assignments`.`id` = 3
希望这可以帮助。
- 可以使用Rails ActiveRecord #save方法更新现有记录吗?
- 用于将ActiveRecordvalidation错误转换为API响应的模式
- Rails 3未定义方法`create’for nil:尝试创建相关对象时出现NilClass错误
- accept_nested_attributes_for:allow_destroy,:_ destroy无效
- 如何在Ruby on Rails中为所有模型动态更改Active Record数据库?
- Rails – 动态构建深层嵌套对象(Cocoon / nested_form)
- Rails模型关联,has_many:through和has_one具有相同的模型
- Ruby on Rails:如何在没有Active Record的情况下validation模型?
- 按ActiveRecord中的特定ID排序