Metodi nel modello


#1

Ciao,
ho questa domanda: ho la classico modello user a cui è associato un
modello “profilo”.

user ha un campo obbligatorio che si chiama ‘login’, e il profilo in
generale non è obbligatorio, e comunque ha un campo che si chiama nome e
un altro cognome

ora vorrei che nelle viste quando si visualizza un utente venga
visualizzato il nome e cognome se sono presenti (e quindi se c’e’ il
profilo), in alternativa vorrei che visualizzasse il login.

Per far questo ho pensato di mettere un metodo del tipo
‘nome_da_visualizzare’ nel modello user, ma non so come fare
(probabilmente vi sembrerà una domanda molto banale, ma non ci riesco lo
stesso…)

class User < ActiveRecord::Base
has_one :profile

end

class Profile < ActiveRecord::Base
belongs_to :user
end

ciao, grazie
Alessandro


#2

2009/2/9 Alessandro A. removed_email_address@domain.invalid:

profilo), in alternativa vorrei che visualizzasse il login.

Per far questo ho pensato di mettere un metodo del tipo
‘nome_da_visualizzare’ nel modello user, ma non so come fare
(probabilmente vi sembrerà una domanda molto banale, ma non ci riesco lo
stesso…)

manca un dato: se profile è presente, nome e cognome sono sicuramente
presenti oppure no?

se
sì,
class User < ActiveRecord::Base
has_one :profile

def name_to_show
profile ? “#{profile.first_name} #{profile.last_name}” : login
end
end

altrimenti:

class User < ActiveRecord::Base
has_one :profile

def name_to_show
(profile && profile.first_name && profile.last_name) ?
“#{profile.first_name} #{profile.last_name}” : login
end
end

solo che così è illegibile, quindi meglio:

def name_to_show
if profile && profile.first_name && profile.last_name
“#{profile.first_name} #{profile.last_name}”
else
login
end
end

ah, questa cosa di fare “#{a} #{b}” invece di a + " " + b oppure [a,
b].join ’ ’ è un vizio mio, l’ho preso anni fa, dopo la prima volta
che ho provato a concatenare 10000000 stringhe in un ciclo for, con
risultati devastanti. in effetti è molto leggibile finché sono #{a} e
#{b}, un po’ meno quando si complica un po’.

meglio sarebbe, forse, definire in Profile:

class Profile < ActiveRecord::Base
def full_name
(first_name && last_name) ? “#{first_name} #{last_name}” : nil
end
end

e poi in user:

def name_to_show
(profile && profile.full_name) || login
end

così credo sia più chiaro, e in più la roba di profile la maneggia
profile, e la roba di user la maneggia user.

pietro


#3

Pietro G. wrote:

2009/2/9 Alessandro A. removed_email_address@domain.invalid:

profilo), in alternativa vorrei che visualizzasse il login.

Per far questo ho pensato di mettere un metodo del tipo
‘nome_da_visualizzare’ nel modello user, ma non so come fare
(probabilmente vi sembrer� una domanda molto banale, ma non ci riesco lo
stesso…)

manca un dato: se profile � presente, nome e cognome sono sicuramente
presenti oppure no?

se
s�,
class User < ActiveRecord::Base
has_one :profile

def name_to_show
profile ? “#{profile.first_name} #{profile.last_name}” : login
end
end

altrimenti:

class User < ActiveRecord::Base
has_one :profile

def name_to_show
(profile && profile.first_name && profile.last_name) ?
“#{profile.first_name} #{profile.last_name}” : login
end
end

solo che cos� � illegibile, quindi meglio:

def name_to_show
if profile && profile.first_name && profile.last_name
“#{profile.first_name} #{profile.last_name}”
else
login
end
end

ah, questa cosa di fare “#{a} #{b}” invece di a + " " + b oppure [a,
b].join ’ ’ � un vizio mio, l’ho preso anni fa, dopo la prima volta
che ho provato a concatenare 10000000 stringhe in un ciclo for, con
risultati devastanti. in effetti � molto leggibile finch� sono #{a} e
#{b}, un po’ meno quando si complica un po’.

meglio sarebbe, forse, definire in Profile:

class Profile < ActiveRecord::Base
def full_name
(first_name && last_name) ? “#{first_name} #{last_name}” : nil
end
end

e poi in user:

def name_to_show
(profile && profile.full_name) || login
end

cos� credo sia pi� chiaro, e in pi� la roba di profile la maneggia
profile, e la roba di user la maneggia user.

pietro

Perfetto!
era esattamente l’aiuto che cercavo.
una curiosità : quando faccio

profile ? “#{profile.first_name} #{profile.last_name}” : login

vengono fatte delle query? potrebbero esserci problemi di prestazioni?

Grazie molte!

Ciao


#4

Il 9 febbraio 2009 11.22, Alessandro A. removed_email_address@domain.invalid ha
scritto:

una curiosità: quando faccio

profile ? “#{profile.first_name} #{profile.last_name}” : login

vengono fatte delle query? potrebbero esserci problemi di prestazioni?

tu hai un oggetto user, che ti sei procurato in qualche modo, o
creandolo ex novo oppure facendo una query, ad esempio User.find(12).

nel momento in cui accedi a user.profile, in qualche modo l’oggetto
profile devi procurartelo. se l’oggetto user l’hai ottenuto con
User.find(12) e poi accedi a user.profile, effettivamente fai un’altra
query.

ma l’oggetto User puoi ottenerlo con User.find(12, :include =>
:profile). in questo modo puoi accedere a user.profile senza il
bisogno di effettuare un’altra query. naturalmente magie non se ne fa:
usare :include nel find fa sì che vengano fatte due query, una su
users, una su profiles. (la cosa diventa però più interessante quando
usi :include su molti record, ovvero quando fai find(:all, :conditions
=> …, :include => :profile).

l’include puoi spostarlo in un named_scope di User:

class User < ActiveRecord::Base
has_one :profile

named_scope :with_profile, {:include => :profile}
end

così puoi usare: User.with_profile.find(…).

c’è anche un modo per mettere l’include in TUTTE le query, ma non
ricordo come si fa e comunque lo sconsiglio, perché non sempre uno
vuole accedere all’altro record.

pietro