Build vs Create in имеет много сквозных отношений

Интересно, может ли кто-нибудь помочь мне понять разницу между сборкой и созданием в отношениях Has Many Through (HMT)?

Насколько я понял после прочтения stackoverflow и google, создать, по сути, построить + сохранить. Однако похоже, что create делает больше, чем просто сборка + сохранение. Это также каким-то образом сохраняется в таблице соединений отношения HMT, как показано ниже.

Я создал 3 модели: пользователь, вики и соавтор.

class User < ActiveRecord::Base
  has_many :wikis, through: :collaborators
  has_many :collaborators
end

class Wiki < ActiveRecord::Base
  has_many :users, through: :collaborators
  has_many :collaborators
end

class Collaborator < ActiveRecord::Base
  belongs_to :user
  belongs_to :wiki
end

Затем я протестировал поведение сборки и создания в консоли rails:

$rails c
Loading development environment (Rails 4.0.10)
> user = User.first  #create instance user
User Load SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
=> #<User id: 1, name: "Jayzz55">

> (user.wikis.build(title:"hello",body:"world")).save  #build and save wiki
SQL INSERT INTO "wikis" ("body", "created_at", "title", "updated_at") VALUES(?,?,?,?) [["body","world"], ["ccreated_at, Sat, 08 Nov 2014 01:39:36 UTC +00:00], ["title","hello"], ["updated_at",Sat, 08 Nov 2014 01:39:36 UTC +00:00]]
=> true

>wiki1 = Wiki.first  #create instance wiki called wiki1
=> #<Wiki id:1, title:"hello",body:"world">

>user.wikis
=> #<Wiki id:1, title:"hello",body:"world">

>user.wikis.count
=> 0

>wiki1.users
=> []

>Collaborator.all
=> []

> user.wikis.create(title:"second title",body:"another one")
begin transaction
SQL INSERT INTO "wikis" ("body", "created_at", "title", "updated_at") VALUES (?, ?, ?, ?)[0m  [["body", "another one"], ["created_at", Sat, 08 Nov 2014 01:59:39 UTC +00:00], ["title", "second title"], ["updated_at", Sat, 08 Nov 2014 01:59:39 UTC +00:00]]
SQL INSERT INTO "collaborators" ("created_at", "updated_at", "user_id", "wiki_id") VALUES (?, ?, ?, ?)  [["created_at", Sat, 08 Nov 2014 01:59:39 UTC +00:00], ["updated_at", Sat, 08 Nov 2014 01:59:39 UTC +00:00], ["user_id", 1], ["wiki_id", 2]]
=> #<Wiki id:2, title:"second title",body:"another one>

>user.wikis
=> [#<Wiki id: 1, title:"hello",body:"world">, #<Wiki id:2, title:"second title",body:"another one>]

>user.wikis.count
=> 1

>wiki2.users
=>#<User id: 1, name: "Jayzz55">

>Collaborator.all
Collaborator Load SELECT "collaborators".* FROM "collaborators"
=> #<Collaborator id:`, user_id:1, wiki_id: 2>

Case wiki1: создайте, а затем сохраните Данные не сохраняются в таблице соединений. вызов user.wikis действительно возвращает объект wiki, но запуск user.wikis.count возвращает 0. Кроме того, запуск wiki1.users не возвращает пользователя объекта. Проверка таблицы соединений Collaborator возвращает пустой массив.

Case wiki2: создать Данные сохраняются в таблице соединения. вызов user.wikis действительно возвращает объект wiki. Выполнение user.wikis.count возвращает 1. Кроме того, выполнение wiki1.users возвращает пользователя объекта. Проверка таблицы соединений Collaborator показывает, что отношения четко отображаются.

Похоже, Create — это не просто сборка + создание. Мне любопытно это поведение, и, надеюсь, кто-то может поделиться своими знаниями об этом.


person Jayzz55    schedule 08.11.2014    source источник
comment
возможный дубликат с использованием has_many :through и build   -  person Substantial    schedule 08.11.2014


Ответы (2)


Я считаю, что если бы вы в своем первом случае вместо этого написали:

user.wikis.build(title:"hello",body:"world")
user.save

... вы обнаружите, что ActiveRecord выполняет «полное» сохранение, которое также делает create. Как вы написали, вы просите ActiveRecord сохранить только что созданный экземпляр Wiki, но не ассоциацию. Таким образом, он не создает необходимую запись в таблице соединений.

person Todd Agulnick    schedule 08.11.2014
comment
Спасибо, Тодд, за объяснение. Теперь я понимаю :) - person Jayzz55; 08.11.2014

«Создать + Сохранить» эквивалентно «Создать» в любых отношениях.

person Hemali    schedule 08.11.2014