Построить против нового в Rails 3
в рельсы 3 docs на build
метод для ассоциаций описывается как то же самое, что и new
метод, но с автоматическим назначением внешнего ключа. Прямо из документов:
Firm#clients.build (similar to Client.new("firm_id" => id))
Я читал подобное в другом месте.
однако, когда я использую new
(например,some_firm.clients.new
без каких-либо параметров), новый клиент firm_id
ассоциации и автоматически создается. Я смотрю на результаты сейчас консоль!
Я что-то пропустила? Документы немного устарели (маловероятно)? В чем разница между build
и new
?
5 ответов:
вы немного неправильно читаете документы.
some_firm.client.new
создает новыйClient
объект из коллекции клиентами, и поэтому он может автоматически установитьfirm_id
доsome_firm.id
, в то время как документы вызываютClient.new
который не имеет никакого знания идентификатора какой-либо фирмы вообще, поэтому он нуждается вfirm_id
перешло к нему.единственная разница между
some_firm.clients.new
иsome_firm.clients.build
кажется, чтоbuild
также добавляет вновь созданный клиентомclients
коллекция:henrym:~/testapp$ rails c Loading development environment (Rails 3.0.4) r:001 > (some_firm = Firm.new).save # Create and save a new Firm #=> true r:002 > some_firm.clients # No clients yet #=> [] r:003 > some_firm.clients.new # Create a new client #=> #<Client id: nil, firm_id: 1, created_at: nil, updated_at: nil> r:004 > some_firm.clients # Still no clients #=> [] r:005 > some_firm.clients.build # Create a new client with build #=> #<Client id: nil, firm_id: 1, created_at: nil, updated_at: nil> r:006 > some_firm.clients # New client is added to clients #=> [#<Client id: nil, firm_id: 1, created_at: nil, updated_at: nil>] r:007 > some_firm.save #=> true r:008 > some_firm.clients # Saving firm also saves the attached client #=> [#<Client id: 1, firm_id: 1, created_at: "2011-02-11 00:18:47", updated_at: "2011-02-11 00:18:47">]
если вы создаете объект через ассоциацию,
build
должно быть предпочтительнееnew
как построить сохраняет ваш объект в памяти,some_firm
(в данном случае) в согласованном состоянии еще до того, как объекты были сохранены в базе данных.
build
- это просто псевдоним дляnew
:alias build new
полный код можно найти: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation.rb
вы правы, сборка и новые функции имеют тот же эффект установки внешнего ключа, когда они вызываются через ассоциацию. Я считаю, что причина, по которой документация написана таким образом, заключается в том, чтобы уточнить, что создается новый клиентский объект, а не новое отношение активной записи. Это тот же эффект, что и вызов .новый класс будет в Рубине. То есть в документации уточняется, что вызов build на ассоциацию-это то же самое создание нового объекта (вызов .new) и передача внешних ключей к этому объекту. Все эти команды эквивалентны:
Firm.first.clients.build Firm.first.clients.new Client.new(:firm_id => Firm.first.id)
Я верю в причину .сборка существует - это та фирма.первый.клиенты.новое может быть интерпретировано как означающее, что вы создаете новый объект отношения has_many, а не фактический клиент, поэтому вызываете .сборка-это способ прояснить это.
build vs new:
в основном новые и построить же, но построить хранит объект в памяти,
например.
на новый:
Client.new(:firm_id=>Firm.first.id)
для сборки:
Firm.first.clients.build
здесь клиенты хранятся в памяти, когда сохранить фирму , связанные записи также сохраняются.
модель.новый
Tag.new post_id: 1
будет создать тегpost_id
set.@модель.модели.новый
@post.tags.build
тут же и экземпляр тега будет находиться в@post.tags
даже до того, как он будет сохранен.это значит
@post.save
сохранит как @post, так и вновь созданный тег (при условии, что :inverse_of установлен). Это здорово, потому что Rails проверит оба объекта перед сохранением, и ни один из них не будет сохранен, если один из них не удастся утверждение.модели.новые модели против.строй
@post.tags.build
и@post.tags.new
эквивалентны (по крайней мере с рельсов 3.2).