2016-03-16 7 views
6

Ho un metodo di classe in cui desidero modificare i record attualmente catturati da un oggetto ActiveRecord::Relation. Ma non so come fare riferimento allo scope corrente in un metodo di classe. self non lo fa.Specificare i record attualmente acquisiti all'interno del metodo della classe Model

Esempio:

class User < ActiveRecord::Base 
    ... 

    def self.modify_those_records 
    #thought implicitly #to_a would be called on currently grabbed records but doesn't work 
    temp_users_to_a = to_a 
    ... 
    end 
end 

vorrei utilizzare in questo modo:

User.some_scope.modify_those_records 

Così User.some_scope sarebbe tornare a me un ActiveRecord::Relation che contiene una serie di User record. Quindi voglio modificare quei record all'interno di quel metodo di classe e quindi restituirli.

Il problema è: non so come fare esplicitamente riferimento a "quel gruppo di record" all'interno di un metodo di classe.

+2

Provare a usare 'current_scope.to_a' – MrYoshiji

+0

Cosa intendi con" afferrato "? –

+0

@MrYoshiji Eccellente! Grazie. Fornisci una risposta in modo che io possa darti credito. – Neil

risposta

4

È possibile utilizzare current_scope:

def self.modify_those_records 
    current_scope.each do |user| 
    user.do_something! 
    end 
end 

Se volete ordinare gli utenti in base ai loro diritti di amministratore, si sarebbe meglio usare ActiveRecord:

scope :order_admins_first, order('CASE WHEN is_admin = true THEN 0 ELSE 1 END, id') 
User.some_scope.order_admins_first 

Questo codice significa che hai una colonna booleana is_admin nella tabella utenti.

2

Direi che una combinazione di uno scope con each e un metodo di istanza è più facile da capire rispetto a un metodo di classe. E come bonus è più facile da testare, in quanto è possibile verificare tutti i passaggi in modo isolato:

Pertanto, invece di User.some_scope.modify_those_records vorrei fare qualcosa di simile:

User.some_scope.each(&:modify) 

e implementare un metodo di istanza:

# in user.rb 
def modify 
    # whatever needs to be done 
end 
+0

La cosa corrente che sto cercando di fare è questa: se un gruppo di utenti ha un utente amministratore: quindi estrarlo e poi spingerlo in primo piano. Non sono sicuro di poterlo fare con un metodo di istanza. Penso che avrei bisogno di farlo con un metodo di classe che cambia l'activerecord in un array, fa quel business e poi restituisce l'array (o lo converte nuovamente in un rapporto di record attivo). Ma potrei sbagliarmi. – Neil

+1

@Neil è possibile fornire agli utenti un campo di ordinamento, 1 per l'amministratore, 0 per gli altri e ordinare decrescente di quello, non è necessario recuperare tutti i record (in quanto ciò potrebbe interrompere l'impaginazione) – Vasfed

+0

@Neil: Come si identificano gli utenti admin? Hanno una bandiera booleana? – spickermann

1

Se si desidera solo modificare l'ordine dei record, il modo migliore è aggiungere un campo di ordinamento (se non ce l'hai già) al modello e ordinare in base a quello.

User.some_scope.order(name: :asc).order(is_admin: :desc) 
Problemi correlati