2011-01-31 5 views
5

Ho un sacco di controller con metodi che rendono la vista indice. Ciò mi porta a scrivere render :index alla fine della maggior parte dei metodi. Ecco un esempioCome posso ASCIUGARE tutte queste chiamate al rendering: indice?

def index 
    @models = Model.find(:all) 
end 

def new_models 
    @models = Model.find_by_new(true) 

    render :index 
end 

def old_models 
    @models = Model.find_by_new(false) 

    render :index 
end 

Idealmente, vorrei solo spostare il codice di rendere in un dopo filtro, ma come il controller effettua una chiamata a rendere prima di andare al dopo filtro che non è un'opzione.

Ho un numero elevato di controller come questo, quindi una soluzione rimuoverà un sacco di codice ripetuto.

Questa app è attualmente ancora Rails 2.3, tuttavia, sarà aggiornata a Rails 3 nei prossimi mesi o due. Quindi, mentre preferirei una tecnica che funzioni su 2.3, le sole soluzioni di Rails 3 sarebbero comunque apprezzate.

+3

solo una nota, cercare di evitare conascenza di significato per quanto possibile. (ho appena * avevo * a usa quella 'parola' per giorno, perche 'ho appena saputo della connascenza **: D **) Vedi http://scotland-on-rails.s3.amazonaws.com/1A03_JimWeirich-SOR.mp4 se interessato – Zabba

+0

E' stata una bella chiacchierata. Grazie per averlo condiviso. Il mio esempio non è un codice che ho davvero scritto. Stavo solo inserendo un codice casuale senza molto per l'esempio. Sono contento di averlo fatto, però, altrimenti non avrei mai saputo della Conascenza :-) –

risposta

4

Se si vuole veramente ASCIUGARE questa azione, e se è molto comune, allora si può fare un po 'di meta-programmazione. Innanzitutto creare un file render_with_index.rb con questa definizione modulo:

 
module RenderWithIndex 
    def self.included klass 
    klass.class_eval do 
     def self.render_with_index * methods 
     methods.each do |method| 
      self.class_eval <<-EVAL 
      alias :old_method :#{method} 

      def #{method} 
       old_method 
       render :index 
      end 
      EVAL 
     end 
     end 
    end 
    end 
end 

quindi includere tale modulo nel controller e definire i metodi che dovrebbero rendere con indice (assicurarsi che la chiamata render_with_index accade dopo le dichiarazioni di metodo

.
 
include RenderWithIndex 

def index 
    @models = Model.find(:all) 
end 

def new_models 
    @models = Model.find_by_new(true) 
end 

def old_models 
    @models = Model.find_by_new(false) 
end 

render_with_index :new_models, :old_models 

Questo modulo consente ora di rendering qualsiasi azione con il modello dell'indice semplicemente aggiungendolo alla chiamata render_with_index.

+0

+1 per un approccio diverso :) – hade

+0

Eccellente :-) Esattamente quello che stavo cercando. –

2

Sembra piuttosto ASCIUTTO per me. IMHO è un buon compromesso per menzionare quale template stai rendendo se non vuoi usare un template specifico per il controller.

Se il codice di rendering si estende da una riga in più righe di codice, DRY li trasformo in un metodo di rendering separato.