Build vs new w Rails 3
W Rails 3 docs, metoda build
dla asocjacji jest opisana jako taka sama jak Metoda new
, ale z automatycznym przypisaniem klucza obcego. Prosto z docs:
Firm#clients.build (similar to Client.new("firm_id" => id))
Czytałem podobne gdzie indziej.
Jednak, gdy używam new
(np. some_firm.clients.new
bez żadnych parametrów), nowe skojarzenie firm_id
jest automatycznie tworzone. Właśnie patrzę na wyniki w konsoli!
Czy coś przeoczyłem? Są dokumenty trochę nieaktualne (mało prawdopodobne)? Jaka jest różnica między build
A new
?
5 answers
Trochę źle odczytujesz dokumenty. some_firm.client.new
tworzy nowy obiekt Client
z kolekcji clients, dzięki czemu może automatycznie ustawić firm_id
na some_firm.id
, podczas gdy docs wywołują Client.new
, który nie ma wiedzy o identyfikatorze żadnej firmy, więc potrzebuje firm_id
przekazanego do niego.
Jedyna różnica pomiędzy some_firm.clients.new
i some_firm.clients.build
wydaje się być taka, że build
dodaje również nowo utworzonego klienta do kolekcji 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">]
Jeśli tworzysz obiekt poprzez skojarzenie, build
powinien być preferowany niż new
, ponieważ build utrzymuje obiekt w pamięci, some_firm
(w tym przypadku) w spójnym stanie, nawet zanim jakiekolwiek obiekty zostaną zapisane w bazie danych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-14 06:59:59
build
jest tylko aliasem dla new
:
alias build new
Pełny kod można znaleźć: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation.rb
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-29 12:25:02
Masz rację, funkcje build i new mają ten sam efekt ustawiania klucza obcego, gdy są wywoływane przez skojarzenie. Wierzę, że powodem, dla którego dokumentacja jest napisana w ten sposób, jest wyjaśnienie, że nowy obiekt klienta jest inicjowany, w przeciwieństwie do nowej relacji active record. Jest to ten sam efekt, co wywołanie .nowy na zajęciach będzie w Ruby. To znaczy, że dokumentacja wyjaśnia, że wywołanie build on a association jest tym samym tworzenie nowego obiektu (wywołanie .nowy) i przekazanie kluczy obcych do tego obiektu. Wszystkie te polecenia są równoważne:
Firm.first.clients.build
Firm.first.clients.new
Client.new(:firm_id => Firm.first.id)
Wierzę w powód .build istnieje to firma.najpierw.klientów.new może być interpretowane w ten sposób, że tworzysz nowy obiekt relacji has_many, a nie rzeczywisty klient, więc wywołujesz .budowanie jest sposobem na wyjaśnienie tego.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-10 07:29:29
Build vs new:
W większości new I build są takie same, ale build przechowuje obiekt w pamięci,
Np.
Dla nowego:
Client.new(:firm_id=>Firm.first.id)
Dla budowy:
Firm.first.clients.build
Tutaj klienci są zapisywani w pamięci, przy zapisie firmowym zapisywane są również powiązane rekordy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-29 12:22:43
Model.Nowy
Tag.new post_id: 1
spowoduje utworzenie znacznika z jego zestawem post_id
.
@ model.modelki.Nowy
@post.tags.build
robi to samo i instancyjny znacznik będzie w @post.tags
, zanim zostanie zapisany.
Oznacza to, że @post.save
zapisze zarówno @post, jak i nowo zbudowany znacznik(zakładając, że ustawiono :inverse_of). Jest to świetne, ponieważ Rails sprawdzi oba obiekty przed zapisaniem i żaden z nich nie zostanie zapisany, jeśli któryś z nich nie powiedzie się walidacji.
Modele.nowy vs modelki.build
@post.tags.build
i @post.tags.new
są równoważne (przynajmniej od Rails 3.2).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-03 18:51:04