2010-10-16 15 views
21

Ho un modello locale e voglio fare questoRails trovare o creare basano su due campi

Venue.find_or_create_by_ 

ma voglio solo una nuova sede per essere creato se uno con lo stesso nome e la data non sono già esistere

ad esempio

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

Terreno è unica e deve essere creato se la posizione e l'showdate non sono presenti nel db

risposta

41

È possibile concatenare le colonne utilizzando _and_. Questo dovrebbe fare il trucco:

Venue.find_or_create_by_location_and_showdate(location, showdate) 
+0

Jeez, Rails e in particolare Ruby mi stupiscono continuamente. Come fa a sapere cosa significa questa funzione? C'è qualche tipo di catch all funzione find_or_create_by_ * che lo interpreta? – Jordan

+7

In realtà, ho appena dato un'occhiata all'origine Rails - Rails utilizza una funzione method_missing che esegue un'espressione regolare sul metodo chiamato e la decompone. È geniale. Se qualcun altro è interessato, controlla active_record/base.rb nell'origine Rails. – Jordan

+0

Anche accettabile è passarli come argomenti. 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 metodo trovare per nome e posizione nel database. Se il record non esiste, inizializza il nuovo record con showdate e posizione. http://api.rubyonrails.org/classes/ActiveRecord/Base.html Questo collegamento ti aiuterà a capire find_or_initialize e find_or_create.

+0

Chiamare ".update_attributes!" Senza passare alcun attributo è abbastanza inutile. '.save!' sarebbe un'opzione molto migliore. E in questo caso, il richiedente ha già detto che vuole usare '.find_or_create', quindi non dovresti dover inizializzare e salvare il record in due passaggi separati. – vonconrad

+0

@vonconrad Ho già fornito un link che dà un'idea di entrambi i metodi. Qualunque utente vorrebbe usarlo. Stavo dando l'idea che entrambi i metodi sono disponibili. –

+1

utilizzando find_or_initialize risolve il problema di provare a creare un record quando ci sono convalide che non vengono soddisfatte da una creazione. per esempio. Migrazione dei dati da un altro sistema. – Gary

7

In rotaie 4 si farebbe:

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

molto più bella, se mi chiedete!

Problemi correlati