Rails Best Practices 3: Aumentare la leggibilità dei controller

[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:

1
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.

1
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:

1
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.

1
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.