Petites questions sur l'utilisation des vues

Bonjour à tous,

je suis actuellement en train d’écrire ma première application RoR, ce
qui m’amène à quelques petites questions.

Imaginons un contrôleur “utilisateurs”, donc la méthode “show” affiche
les informations liées à cet utilisateur, mais également d’autres
éléments (1,n) comme par exemple la liste des groupes auquel il
appartient. Donc, dans la vue utilisateur/show, est ce mal de faire un
render partial sur la vue groupe/show ?

D’autre part, j’utilisais à l’origine un layout unique
(application.rhtml donc), mais j’ai intégré dans celui ci un sous menu
qui est dépendant du contrôleur appelant. Quelle est la solution la plus
propre pour définir le menu depuis la vue appelante ?

Pour l’instant j’ai renommer mon application.rhtml en _application, je
rempli un tableau depuis mon layout/utilisateur.rhtml et je fais un
render :partial d’application, y a t’il une solution plus propre ?

Y t’il une solution plus élégante ?

Merci d’avance

<%= case controller.controller_name
controller.controller_name %>
# code menu Main
end %>

Si j’ai bien compris la problematique, je pense que ca peut aider.

Dans ta vue principale ici application.rhtml, tu peut mettre ceci

<%= yield :navbar =%>
en lieu et place de ton menu.

Puis dans la vue correspondante a l’action, tu defini un block
content_for

par ex dans Accounts/index.rhtml

<% content_for :navbar do %>
le code de ton menu
<% end %>
Lors du rendu le resultat du block content_for :navbar ira se mettre
automatiquement a la place du yield :sidebar
Si yield :sidebar ne trouve pas de block content_for correspoindant,
rien
ne sera rendu.

Voila HTH

Salut

je suis actuellement en train d’écrire ma première application RoR,
cool

Imaginons un contrôleur “utilisateurs”, donc la méthode “show” affiche
les informations liées à cet utilisateur, mais également d’autres
éléments (1,n) comme par exemple la liste des groupes auquel il
appartient. Donc, dans la vue utilisateur/show, est ce mal de faire un
render partial sur la vue groupe/show ?
Non au contraire, c’est très bien. Je fais ainsi personnellement, je
trouve ça sépare les vues intelligemment ; mais c’est essentiellement
une question de préférence.

D’autre part, j’utilisais à l’origine un layout unique
(application.rhtml donc), mais j’ai intégré dans celui ci un sous menu
qui est dépendant du contrôleur appelant. Quelle est la solution la
plus
propre pour définir le menu depuis la vue appelante ?
Pour l’instant j’ai renommer mon application.rhtml en _application, je
rempli un tableau depuis mon layout/utilisateur.rhtml et je fais un
render :partial d’application, y a t’il une solution plus propre ?

Y t’il une solution plus élégante ?

Il n’y a pas de solution idéale dans ce contexte :frowning:
Celle tu pratiques paraît tout à fait honnête.

Perso si j’ai des sous-menus j’utilise controller.controller_name
avec un case-when ou if-elsif dans application.rhtml

ex rapide :

<%= case controller.controller_name
when ‘Accounts’
render :partial => ‘/accounts/menu’
when ‘Addresses’
render :partial => ‘/addresses/menu’
else
render :partial => ‘/main/menu’
end %>

Tu peux aussi mettre tous tes menus au même endroit :
<%= render :partial => ‘/shared/menu2’, :object =>
controller.controller_name %>

et refaire le case when dans /shared/menu2.rhtml, mais là avec tout
le code de tous tes menus

<%= case menu2
when ‘Accounts’
# code menu Accounts
when ‘Addresses’
# code menu Addresses
else
# code menu Main
end %>

Bonne chance,
NP_______________________________________________
Railsfrance mailing list
[email protected]
http://lists.rubyonrails.fr/mailman/listinfo/railsfrance

re

par ex dans Accounts/index.rhtml

<% content_for :navbar do %>
le code de ton menu
<% end %>
Lors du rendu le resultat du block content_for :navbar ira se
mettre automatiquement a la place du yield :sidebar
Si yield :sidebar ne trouve pas de block content_for
correspoindant, rien ne sera rendu.

Oh, je ne connaissais pas ! Ca peut être méchamment pratique comme
système. Merci Guillaume !

NP_______________________________________________
Railsfrance mailing list
[email protected]
http://lists.rubyonrails.fr/mailman/listinfo/railsfrance

J’avais remarqué que le <%= @content_for_layout %> avait été remplacé
par <%= yield %> mais je n’avais pas fait attention.

Ce changement a été introduit dans la version 1.1.5 par Marcel Molina
Jr.
(Peak Obsession).
Dans un article de Kevin C. sur Gluttonous
(http://glu.ttono.us/articles/2006/03/21/rails-for-designers),
quelqu’un pose la question dans les commentaires, et l’auteur répond :
“yield is prefered because it allows the core developers to change
what happens in the backend more easily than an accessible instance
variable (which is what @content_for_layout is). They’re looking for
long term maintainability, and yield is better to that end. yield is
also more Ruby-like.”

Mais qu’est-ce que “yield” ?
En Ruby, yield permet d’exécuter le code du bloc qui a été passé à la
méthode courante. Par exemple :

def threeTimes
yield
yield
yield
end
threeTimes { puts “Hello” }

affiche :

Hello
Hello
Hello

(exemple honteusement recopié depuis Ruby Central
(http://www.rubycentral.com/book/tut_containers.html))

Si on veut lui passer des arguments :

def threeTimes
yield “Bruno”
yield “Nicolas”
yield “Guillaume”
end
threeTimes { |cool_guy| puts "Hello " + cool_guy }

affiche :

Hello Bruno
Hello Nicolas
Hello Guillaume

On retrouve la forme connue des my_array.each { |element| code }.

En fouillant dans la liste de Rails, je suis tombé sur un message
intéressant expliquant que la forme yield :symbol remplaçait celle de
content_for :symbol
(http://lists.rubyonrails.org/pipermail/rails/2006-June/044707.html).
Et enfin, dans le code d’ActionView, on peut lire que pour chacune des
variables @content_for, le code qu’elles contiennent est exécutée
(http://dev.rubyonrails.org/browser/trunk/actionpack/lib/action_view/base.rb?rev=3314#L292).

Bref, un layout dans le layout comme on peut le lire à droite ou Ã
gauche.

Merci encore à Guillaume GARCERA d’avoir montré ça, car moi non plus
je ne connaissais pas, et ça permettra de rendre mon layout principal
encore plus dynamique, par exemple avec un <% content_for :meta do %>
… <% end %> ou autres, pour des parties de la page qui ne sont pas
le contenu principal.

PS : je me rends compte que je vous ai raconté mes recherches, et que
peut-êytre ça passionnera pas grand monde, alors, pour qu’il y ait un
contenu correct, que tout le monde s’accorde à qualifier de valable,
je n’ajouterai qu’une chose : “Chunky Bacon !”

PS : je me rends compte que je vous ai raconté mes recherches, et que
peut-êytre ça passionnera pas grand monde, alors, pour qu’il y ait un
contenu correct, que tout le monde s’accorde à qualifier de valable,
je n’ajouterai qu’une chose : “Chunky Bacon !”

Si si, ca passionne au moins les débutants comme moi, ceux qui ont le
plus à apprendre, donc c’est très bien, et du coup, ca me motive à poser
d’autre questions :slight_smile:

Merci encore à vous, je vais regarder tout ca de près.

Puisqu’on parle de yield, est-ce qu’on peut dire que “yield permet de
passer à une fonction anonyme à une méthode” ?
Si non, qu’est-ce qui serait une bonne explication en français ?

++

yk

Guillaume “Zifro” DESRAT a écrit :

Puisqu’on parle de yield, est-ce qu’on peut dire que “yield permet de
passer à une fonction anonyme à une méthode” ?
Si non, qu’est-ce qui serait une bonne explication en français ?

yield permet d’invoquer le bloc (la fonction anonyme) passé à la
méthode courante ?

Non, comme je l’ai écris : “yield permet d’exécuter le code du bloc
qui a été passé à la
méthode courante”.

On peut dire que yield exécute la fonction anonyme passée à la méthode
dans laquelle yield est appelé. C’est un pas vers la généricité.

Dans le code, on peut appeler block_given? qui retourne vrai si un
bloc à été passé à la méthode. Par exemple :

irb(main):001:0> def greet(who)
irb(main):002:1> if block_given?
irb(main):003:2> yield who
irb(main):004:2> else
irb(main):005:2* puts “I don’t know how to greet you #{who}…\n”
irb(main):006:2> end
irb(main):007:1> end
=> nil
irb(main):008:0> greet(“Mamooth”) { |dude| puts “Hello #{dude}\n” }
Hello Mamooth
=> nil
irb(main):009:0> greet(“Mamooth”) { |dude| puts “Gimme cash #{dude}\n” }
Gimme cash Mamooth
=> nil
irb(main):010:0> greet(“Mamooth”)
I don’t know how to greet you Mamooth…
=> nil

En faite j’ai trouvé cela il n’y a pas si longtemps dans un des
projet de railsdays2006, j’ai eu un peu de mal a saisir au départ
puis je l’ai revu dans les sources de Mephisto le CMS/Blog de Rick
Olson et Justin Palmer et la j’ai compris la puissance de la chose.
Maintenant je l’utilise dans mes projets et c’est vraiment super
pratique pour gérer les sidebars et les headers (pour inclure une
autre css ou d’autres js dans certaine page et pas d’autres)
Comme quoi lire quelques sources ca peut aider.

Dans un genre similaire, j’ai trouvé cela avant hier : http://

tres sympa aussi pour gérer les sidebars.

Voila HTH et content d’avoir été utile.

PS : je me rends compte que je vous ai raconté mes recherches, et que
peut-êytre ça passionnera pas grand monde, alors, pour qu’il y ait un
contenu correct, que tout le monde s’accorde à qualifier de valable,
je n’ajouterai qu’une chose : “Chunky Bacon !”


Guillaume G.
[email protected]
11 Rue de Toulouse
78120 Rambouillet

Autre exemple de généricité, en utilisant des blocs que l’on passe aux
fonctions (ou pas…) :

irb(main):001:0> def greet (who, how=nil)
irb(main):002:1> if how.nil?
irb(main):003:2> puts “I don’t know what to say #{who}… "let’s
be friends" ?\n”
irb(main):004:2> else
irb(main):005:2* how.call(who)
irb(main):006:2> end
irb(main):007:1> end
=> nil
irb(main):008:0> hello = proc {|cool_guy| puts “Hello #{cool_guy} !\n”}
=> #Proc:0x7f0964a0@:8(irb)
irb(main):009:0> wtf = proc {|dude| puts “I want to date you #{dude}\n”}
=> #Proc:0x7f08c4dc@:9(irb)
irb(main):010:0> greet “Mamooth”
I don’t know what to say Mamooth… “let’s be friends” ?
=> nil
irb(main):011:0> greet “Mamooth”,hello
Hello Mamooth !
=> nil
irb(main):012:0> greet “Mamooth”,wtf
I want to date you Mamooth
=> nil

La méthode greet sert à saluer les gens (paramètre “who”), et on peut
lui passer la façon de saluer les gens (paramètre “how”, qui vaut nil
par défaut, si on ne le renseigne pas).

Avec “hello = proc { |cool_guy| puts “Hello #{cool_guy} !\n” }”, on
crée une fonction anonyme (il est important de rajouter proc dans ce
cas là ) qui va prendre en argument “cool_guy”, pour le saluer comme il
se doit. La variable “hello” sert à stocker l’objet Proc qui est
créer.

Ensuite, on peut appeler greet avec comme paramètre obligatoire le nom
de la personne (ou du bot) que l’on va saluer, et lui passer la
variable contenant le code pour saluer comme on l’entend la personne.
On lance l’exécution d’un bloc (d’un objet Proc) en appelant la
méthode “call”, à laquelle on peut, éventuellement, passer des
arguments.

Ceci permet un niveau supplémentaire d’abstraction, c’est une forme de
généricité (Généricité — Wikipédia).

Salut Guillaume,

J’avais remarqué que le <%= @content_for_layout %> avait été remplacé
par <%= yield %> mais je n’avais pas fait attention.

Plus exactement l’utilisation de yield plutôt que @content_for_…
est préconisée mais les deux pouvaient s’utiliser indifféremment.

Ce changement a été introduit dans la version 1.1.5 par Marcel Molina
Jr. (Peak Obsession).

Je ne crois pas. noradio a participé au fait de supprimer toutes les
mentions
de @content_for_… dans le code, pour aller dans le sens de la
préconisation
de yield et d’une plus grande cohérence, ainsi par exemple dans le
layout
généré lors d’un scaffold. Mais la fonctionnalité de pouvoir utiliser
yield en
lieu et place de @content_for… existait bien avant 1.1.5 et est au
moins
dispo depuis la séries 0.14.* Rien n’empêchait son utilisation dans 1.0

Une remarque à propos de yield, l’association Ruby France aurait pu
s’appeler
comme cela, il y avait une proposition dans ce sens… (heureusement
non retenue car ç'aurait fait un peu trop geek à mha).

– Jean-François.

re

Dans un genre similaire, j’ai trouvé cela avant hier : http://
Colored Tests — err.the_blog
Oh marrant, je suis tombé sur ce blog hier et c’est le seul article
que je n’ai pas lu :slight_smile:
errtheblog est récent mais la plupart des articles y sont intéressants.

De la même manière les gars de StreetEasy ont un blog récent Ã
notsostupid.com avec 2-3 petites combines genre ça :

puts (patient.name.first_name rescue “-- no name --”)

J’adore !

J’ai déjà dit merci aux Guillaumes pour content_for ? Merci !

NP

Ce changement a été introduit dans la version 1.1.5 par Marcel Molina
Jr. (Peak Obsession).

Je ne crois pas. noradio a participé au fait de supprimer toutes les mentions
de @content_for_… dans le code, pour aller dans le sens de la préconisation
de yield et d’une plus grande cohérence, ainsi par exemple dans le layout
généré lors d’un scaffold. Mais la fonctionnalité de pouvoir utiliser yield en
lieu et place de @content_for… existait bien avant 1.1.5 et est au moins
dispo depuis la séries 0.14.* Rien n’empêchait son utilisation dans 1.0

Oui, pardon, c’est Marcel Molina Jr. qui l’a noté dans le changelog…