Вопрос по ruby-on-rails – Когда сохраняются объекты Active Record в отношениях has_many?

3

Я использую 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!.

Однако, Прагматичные Программисты & apos;Agile Web Development with Rails, Second Edition, который я использовал в качестве учебного пособия и справочника, говорит:

If the parent object exists in the database, then adding a child object to a collection automatically saves that child.

Кажется, здесь есть противоречие. Я хотел бы знать следующее:

  • If I do some_user.assignments.build, is the Assignment object saved?
  • If I do some_user.assignments << Assignment.new, is the Assignment object saved?
  • If I do some_user.assignments << Assignment.create, are two database calls made, or just one? What about if I modify the Assignment object between creating it and adding it to some_user.assignments?
  • What happens if I save! an Assignment object whose corresponding User has not yet been saved in the database?

Постскриптум Причина, по которой я не просто используюUser#assignments.create ибо все потому, что он не позволяет мне перебирать инициализацию для внешнего метода, что я хотел бы иметь возможность делать. Я также не хочу совершать многократные поездки в базу данных.

Ваш Ответ

1   ответ
17

NOTE: All the console tests below are run in Rails 3. You might get a different output in Rails 1, you'll have to run the tests yourself to compare.

Error: User Rate Limit Exceeded

u = User.new
#<User id: nil, name: nil, created_at: nil, updated_at: nil> 

u.assignments.build(:name => "example")
#<Assignment id: nil, name: "example", user_id: nil, created_at: nil, updated_at: nil>

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)

Error: User Rate Limit Exceeded

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')
#<User id: 2, name: "test", created_at: "2012-06-01 19:27:21", updated_at: "2012-06-01 19:27:21"> 

u.assignments.build(:name => "example")
#<Assignment id: nil, name: "example", user_id: 2, created_at: nil, updated_at: nil>

Error: User Rate Limit Exceeded

If I do some_user.assignments.build, is the Assignment object saved?

Error: User Rate Limit Exceeded

If I do some_user.assignments << Assignment.new, is the Assignment object saved?

Error: User Rate Limit Exceeded

If I do some_user.assignments << Assignment.create, are two database calls made, or just one?

Error: User Rate Limit Exceeded

What about if I modify the Assignment object between creating it and adding it to some_user.assignments?

Error: User Rate Limit Exceeded

What happens if I save! an Assignment object whose corresponding User has not yet been saved in the database?

Error: User Rate Limit Exceeded

u = User.new(:name => "John Doe")
#<User id: nil, name: "John Doe", created_at: nil, updated_at: nil> 

a = Assignment.new(:name => "test")
#<Assignment id: nil, name: "test", user_id: nil, created_at: nil, updated_at: nil> 

u.assignments << a
#[#<Assignment id: nil, name: "test", user_id: nil, created_at: nil, updated_at: nil>] 

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

Error: User Rate Limit Exceeded

Благодарю. Знаете ли вы, что означала книга, когда говорилось, что ребенок был спасен автоматически? Taymon
Конечно. Это означало, что ребенок сохранялся автоматически при сохранении его родителя. Таким образом, вам не нужно звонить в службу сохранения как для назначений, так и для пользователей. Назначения автоматически сохраняются, когда пользователи также, но не перед сохранением пользователей.

Похожие вопросы