2013-10-18 13 views
8

vorrei aggiornare la updated_at per un paio di record:Come toccare più record in ActiveRecord?

users = User.in_mailing_list 
users.update_all(:updated_at => Time.now) 

C'è una scorciatoia per lo scopo, dire qualcosa come un metodo users.touch_all?

+0

Non vedo alcun motivo per cui non è possibile estendere 'ActiveRecord :: Base' con qualsiasi metodo di utilità che ti piace – synapse

+0

@synapse evitare di reinventare una ruota. – ohho

risposta

0

Questo dovrebbe farlo:

User.update(users, :updated_at => Time.now) 
5

Non sono sicuro se la risposta di rhernando lavora in vecchie versioni di Ruby, ma questo è un metodo molto più chiara a mio parere e lavora in Ruby 2+

users.each(&:touch) 
  • NB. Come menzionato nei commenti, ciò causerà N richieste invece di usare update_all che lo farebbe in un unico comando.
+5

Questo emetterà query _n_ inutilmente. 'users.update_all updated_at: Time.now' lo fa con 1 query. –

+1

È necessario se si desidera che le richiamate vengano attivate al tocco. API doco per update_all: "Non crea un'istanza dei modelli coinvolti e non attiva i callback o le convalide di Active Record." –

+2

@LucasNelson 'touch' non li attiverà neanche. Come per i documenti: 'non viene eseguita alcuna convalida e vengono eseguiti solo i callback after_touch, after_commit e after_rollback. Ref: http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-touch – vedant1811

4

Si può fare in questo modo:

User.update_all({updated_at: Time.now}, {id: user_ids}) 

Nota: Sono necessarie le parentesi graffe, altrimenti si cerca di impostare updated_ateid, invece di aggiornare updated_atdoveid è in user_ids

Cheers!

+4

Questo potrebbe anche essere scritto come 'User.where (id: user_ids) .update_all (updated_at: Time.now)' – JackCollins

+0

Molto utile, quando si esegue un aggiornamento di massa per molti modelli e si desidera attivare l'impostazione del timestamp updated_at! Grazie! –

1

Se è necessario toccare i record ActibeRelaton, è necessario utilizzare il metodo update_all. Si tocca più record IT singola transazione:

User.update_all(updated_at: Time.current) 
User.where(active: true).update_all(active: false) 

Ma se avete Array di record, in questo caso, è usare solo each con update

users.each { |user| update(activ: true) } 

lo svantaggio di questo caso: per ogni user volontà essere transazione separata

Problemi correlati