2010-05-01 18 views
9

Nei miei precedenti progetti di apprendimento ho sempre utilizzato un singolo controller, ma ora mi chiedo se sia una buona pratica o anche sempre possibile.Il frontend e il backend dovrebbero essere gestiti da diversi controller?

In tutti i tutorial RESTful Rails i controller dispongono di una show, una edit e una vista index. Se un utente autorizzato è connesso, la vista edit diventa disponibile e la vista index mostra ulteriori controlli di manipolazione dei dati, come un pulsante di eliminazione o un collegamento alla vista edit.

Ora ho un applicazione Rails che cade esattamente in questo schema, ma la vista index non è riutilizzabile:

  1. L'utente normale vede una pagina di indice appariscente con un sacco di immagini, layout complessi, nessun requisito Javascript , ...
  2. L'indice utente Admin ha un design completamente diverso minimalista, tavolo jQuery e un sacco di dati aggiuntivi, ...

Ora io non sono sicuro di come gestire questo caso. Mi viene in mente quanto segue:

  1. Controller singolo, unico punto di vista: la vista è diviso in due grandi blocchi/parziali utilizzando un if dichiarazione.
  2. Controller singolo, due visualizzazioni: index e index_admin.
  3. Due diversi controller: BookController e BookAdminController

Nessuna di queste soluzioni sembra perfetto, ma per ora io sono incline a utilizzare l'opzione 3.

Qual è il modo preferito per farlo?

risposta

15

Mi sono posto questa domanda quasi ogni volta che ottengo un nuovo progetto. Di solito scelgo una delle due soluzioni:

1). Single Controller, Single View

Non ho quasi mai scelto questa soluzione ora un giorno a meno che il progetto sia davvero semplice e solo uno o due tipi di utenti. Se si ottengono più tipi di utenti, è meglio utilizzare la soluzione n. 2. Anche se questa soluzione potrebbe essere allettante perché si pensa di risparmiare tempo scrivendo meno codice, ma alla fine il controller e la vista diventeranno più complessi. Per non parlare di tutti i casi limite che devi considerare. Questo di solito significa bug.

La mia azienda ha dovuto salvare un progetto fallito, aveva 3 tipi di utenti.(amministratore, azienda e membro). Hanno usato la soluzione n. Il codice era in condizioni orribili (ed è per questo che ci è stato chiesto di salvare questo progetto). Dicevamo scherzando che non era MVC, era MMM. (Model-Model-Model) Questo perché la logica aziendale non è stata estratta e inserita correttamente nei modelli, ma si è diffusa anche in controller e viste.

2). Multiple Controller, Multiple Views

Io uso questa soluzione sempre di più in questi giorni. Di solito, spazio ai nomi dei controller con tipi di utenti. Per esempio:

In "app/controllori"

class BookController < ApplicationController 
end 

e in "app/controllers/admin"

class Admin::BookController < Admin::BaseController 
end 

ho solo bisogno di prendere in considerazione gli utenti regolari quando riempio in BookController, e devo solo considerare gli utenti admin quando compilo Admin::BookController

Non sono sicuro che ci siano modi migliori, ma questo è quello che ho imparato da una dozzina di progetti che ho fatto finora ...

2

Utilizzare due corrente se ci sono due moduli 1] Admin 2] Utente

Say

class BookUserController < ApplicationController 
    #Here layout is used will be of layouts/application.html.erb 
    #Here all the methods which user can will be present 
end 


class BookAdminController < ApplicationController 
    layout 'admin' #here we set the layout is layouts/admin.html.erb 

end 

se solo una pagina che si desidera visualizzare di amministrazione è possibile utilizzare controller di singolo e due metodi

class BookUserController < ApplicationController 
    layout 'admin', :only=>['index_admin'] 

    def index_admin 


    end 

    def index 



    end 


end 

O

class BookUserController < ApplicationController 
    def index_admin 

    render :action=>'index_admin', :layout => false 
    end 

    def index 



    end 


end 
3

Quello che faccio in una situazione del genere è cambiato un po 'di recente. L'approccio attuale è il seguente:

I controllori separati in base ai requisiti di accesso. Questo mi dà un chiaro modello mentale e un modo molto semplice per controllare il controllo degli accessi (e testarlo).

Mi spingo fino al punto di separare il "proprio accesso" ai modelli in un controller separato . Inoltre, di solito mantengo il nome del controller appena inserito in uno spazio dei nomi separato .

Questo approccio semplifica inoltre l'utilizzo delle implementazioni di controller standard come InheritedResources.

Si noti che è possibile riutilizzare molte visualizzazioni se è richiesta la stessa funzionalità per diversi tipi di accesso.

Così mi piacerebbe avere qualcosa di simile:

### lets start with routes 

# this is basically guest access level. you can only list it and see details 
map.resources :books, :only => [:index, :show] 

namespace :my do |my| 
    # this will require at least login. 
    # index and show will be basically same as at the guest level. we can reuse the views 
    my.resources :books 
end 

namespace :admin do |admin| 
    # this will require admin login 
    admin.resources :books 
end 

# now the controllers 

# this might be just enough of a controller code :). the rest goes into model. 
class BooksController < InheritedResources::Base 
    actions :index, :show 
end 

module My 
    class BooksController < InheritedResources::Base 
    before_filter :require_user 

    protected 
    def begin_of_association_chain 
     # this will force resources to be found on current_user.books. 
     # so if you go to /my/books/123 and book 123 is not your book you will get 404 
     current_user 
    end 
    end 
end 

module Admin 
    class BooksController < InheritedResources::Base 
    before_filter :require_admin 

    # this controller is essentially unrestricted. you can get/edit/update any book 
    # and you can have separate view template for index too 
    end 
end 



## Views 
# well, this is the part that I like the least in this approach, but 
# I think the good outweight the bad. 
# I see 2 ways to reuse the views w/o writing lots of ugly customization code for the InheritedResources 
# 1) render 'parent' views inside templates. i.e. like: 
# my/books/index.html.haml: 
!= render :file => "/books/index" 

# or just link the templates on the filesystem level with symlinks. 
# (or if all of them are the same you can link the directory) 
1

Quando ho bisogno di un area di amministrazione chiaramente separato, mi tendono ad andare per una soluzione con due controller per una risorsa. Un Admin :: BooksController nella directory admin/sub per l'interfaccia di amministrazione con tutte le azioni e un PublicController pubblico che ha solo indici e metodi di visualizzazione in base alle esigenze.

Problemi correlati