Forum: Italian Ruby user group metodi nel modello

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Alessandro A. (Guest)
on 2009-02-09 10:25
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
Pietro G. (Guest)
on 2009-02-09 10:37
(Received via mailing list)
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
Alessandro A. (Guest)
on 2009-02-09 12:22
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
Pietro G. (Guest)
on 2009-02-09 12:57
(Received via mailing list)
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
This topic is locked and can not be replied to.