[POST AGGIORNATO IL 19/07/2010 - 15:45]
Proseguendo la nostra analisi delle Rails Best Practices oggi vediamo altri due accorgimenti per rendere più leggibili i metodi del controller.
1. Metodi nel model
Supponiamo di avere la classica anagrafica utenti e che sia definito un utente admin che ha la possibilitò di attivare/disattivare gli altri utenti.
Scrivendo il metodo deactivate del Controller user probabilmente lo definiremmo come segue:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class UserController < ApplicationController
def deactivate
@user = User.find(params[ :id])
if @user.admin?
flash[:error] = "You can not deactivate Admin user"
else
if @user.update_attributes(:status, "N"))
@user.modified_by = current_user
@user.save
else
flash[:error] = "Error during user deactivation"
end
end
redirect_to :action => 'index'
end
end
Ciò che è evidente è che in questo metodo è presente un sacco di logica. Vediamo allora come definire un metodo nel Model User che contenga la logica per snellire questo metodo.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class User < ActiveRecord:Base
def deactivate(user)
ret = false
self.status = "N"
if self.update_attributes(:status, "N"))
self.modified_by = user
self.save
ret = true
end
ret
end
end
class UserController < ApplicationController
def deactivate
@user = User.find(params[ :id])
if @user.admin?
flash[:error] = "You can not deactivate Admin user"
else
if !@user.deactivate(current_user)
flash[:error] = "Error during user deactivation"
end
redirect_to :action => 'index'
end
end
end
Questa riscrittura rende il metodo deactivate del Controller più leggibile e più facilmente testabile.
2. Factory Method
In modo simile a quanto fatto per il metodo deactivate può risultare comodo, nel caso di metodi create, definire nel model un Factory Method che contenga la logica di creazione/inizializzazione dell’oggetto e successivamente richiamarlo dal Controller.
Vediamo come al solito un esempio.
Immaginiamo di sviluppare un sistema di gestione di news dove la news dev’essere associata all’utente che l’ha creata e deve essere visibile solo per una settimana.
L’implementazione che non fa uso del Factory Method è la seguente:
2
3
4
5
6
7
8
9
10
class PostController < ApplicationController
def create
@post = Post.new(params[:post])
@post.user = current_user
@post.expiring_date = Time.now + 7.day
@post.save
end
end
Vediamo ora come definire un apposito metodo (il factory method) di creazione della news nel Model al fine, ancora una volta, di semplificare il Controller.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Post < ActiveRecord:Base
def publish_new_post(params, user)
post = Post.new(params)
post.user = user
post.expiring_date = Time.now + 7.day
post.save
end
end
class PostController < ApplicationController
def create
@post = Post.publish_new_post(params[:post], current_user)
end
end
Ancora una volta siamo riusciti a rendere il Controller più pulito muovendo la logica nel Model.
Con questo post si conclude la prima parte di questa serie in cui ho cercato di illustrare alcune best practices per semplificare i Controller e spostare la logica di business nei Model.
Dal prossimo post inizierò ad illustrare alcune best practices applicabili ai Model.