2010-10-16 13 views
21

Mam modelu miejsce i chcę zrobić toRails znaleźć lub utworzyć na podstawie dwóch pól

Venue.find_or_create_by_ 

ale chcę tylko nowy obiekt ma zostać utworzony, jeśli jeden z tą samą nazwą i datą nie robić już istnieją

Przykładowo

=> Venue(id: integer, location: string, showdate: datetime, created_at: datetime, updated_at: datetime) 

miejscem jest niepowtarzalny i musi być utworzony, gdy lokalizacja i showdate nie są obecne w db

Odpowiedz

41

Możesz łączyć ze sobą kolumny za pomocą _and_. To powinno załatwić sprawę:

Venue.find_or_create_by_location_and_showdate(location, showdate) 
+0

Jeez, Rails, a szczególnie Ruby ciągle mnie zadziwia. Skąd wie, co oznacza ta funkcja? Czy istnieje jakiś rodzaj funkcji catch find_or_create_by_ *, która je interpretuje? – Jordan

+7

Właściwie nigdy nie myśl, po prostu rzuciłem okiem na źródło Railsów - Rails używa funkcji method_missing, która wykonuje wyrażenie na metodę, która go wywołuje i rozkłada. To geniusz. Jeśli ktoś jest zainteresowany, sprawdź active_record/base.rb w źródle Rails. – Jordan

+0

Akceptowalne jest również przekazanie ich jako argumentów. Venue.find_or_create_by (: location => location,: showdate => showdate) –

1
my_class = ClassName.find_or_initialize_by_showdate_and_location(showdate,location) 
my_class.update_attributes! 

find_or_initialize Znajdź metodę według nazwy i lokalizacji w bazie danych. Jeśli rekord nie istnieje, to inicjuje nowy rekord z datą i lokalizacją. http://api.rubyonrails.org/classes/ActiveRecord/Base.html Ten link pomoże Ci znaleźć find_or_initialize i find_or_create.

+0

Wywoływanie '.update_attributes!' Bez przekazywania jakichkolwiek atrybutów jest całkiem bezużyteczne. '.save!' będzie znacznie lepszą opcją. W tym przypadku requester powiedział już, że chce użyć '.find_or_create', więc nie powinieneś inicjować i zapisywać rekordu w dwóch osobnych krokach. – vonconrad

+0

@vonconrad Podałem już link, który daje pojęcie o obu metodach. Cokolwiek użytkownik chciałby z niego skorzystać. Dałem ci pomysł, że obie metody są dostępne. –

+1

użycie find_or_initialize eliminuje problem z próbą utworzenia rekordu, gdy istnieją walidacje, które nie są spełnione przez kreację. na przykład Migracja danych z innego systemu. – Gary

7

w szynach 4 byś zrobił:

Venue.find_or_create_by(location: location, showdate: showdate) 

Znacznie ładniejszy, jeśli chodzi o mnie!

Powiązane problemy