Forum: Rails France Utilisation de la méthode select de F ormOptionHelper

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.
E4afabbb2fb6a2ea022df381b08b781e?d=identicon&s=25 Samoht Thomas (Guest)
on 2007-03-02 00:14
(Received via mailing list)
Salut,

je sèche un peu là.
J'ai une table de hachage du type "code" => "valeur", par exemple "H" =>
"Homme".
Je voudrai à partir de cette table créer une balise select avec comme
clés/valeurs celles de la table de hashage.

Cela dit la doc n'est pas très explicite...et j'ai l'impression que
l'exemple fournit dans le bouquin O'Reilly "Pratique de Ruby On Rails"
n'est
plus d'actualité.

Ou alors je suis à côté de plaque!...en tant que bon débutant c'est bien
probable!

Quelqu'un à une idée?

Thomas
Ee01e594333a9e631173d0d8e4350214?d=identicon&s=25 didier lafforgue (Guest)
on 2007-03-02 03:21
(Received via mailing list)
Ola Thomas,

Grace a toi, j'ai trouve un truc donc je ne soupconnais pas l'existence.
En
gros, j'ai ouvert ma console RoR (script/console) et cree rapidos une
hash:
> test = { :foo => 'foo', :bar => 'bar' }
et la, je sais pas ce qu'il m'a pris mais j'ai tape un truc incense
> test.collect
O miracle (je rigole pas en plus), le resultat fut exactement ce que je
voulais
=> [[:foo, "foo"], [:bar, "bar"]]

Le resultat obtenu peut etre utilise avec la methode options_for_select
(avec select_tag) ou bien directement avec select. A toi de voir.

  Did

p.s.: c'est fou ruby qq fois, le fait de pouvoir comme cela "ameliorer"
les
classes de base est vraiment qq fois de fascinant.


Le 01/03/07, Samoht Thomas <samohtrgv@gmail.com> a écrit :
669e19951b848d1b0dac78655e34c2a4?d=identicon&s=25 Simon Pasquier (Guest)
on 2007-03-02 08:08
(Received via mailing list)
didier lafforgue wrote:
> => [[:foo, "foo"], [:bar, "bar"]]
>
> Le resultat obtenu peut etre utilise avec la methode
> options_for_select (avec select_tag) ou bien directement avec select.
> A toi de voir.
Euh, par contre il faut appeler la method invert sur la hash pour avoir
<option value-="code">valeur</option>:

 >> {:f => 'Femme', :h => 'Homme' }.collect
=> [[:f, "Femme"], [:h, "Homme"]]
 >> {:f => 'Femme', :h => 'Homme' }.invert.collect
=> [["Femme", :f], ["Homme", :h]]

Mais encore mieux, options_for_select() accepte indifferemment un
tableau ou une hash:
 >> helper.options_for_select( {:f => 'Femme', :h => 'Homme'
}.invert.collect)
=> "<option value=\"f\">Femme</option>\n<option
value=\"h\">Homme</option>"
 >> helper.options_for_select( {:f => 'Femme', :h => 'Homme' }.invert)
=> "<option value=\"f\">Femme</option>\n<option
value=\"h\">Homme</option>"

Et select() egalement
 >> helper.select :person, :gender, {:f => 'Femme', :h => 'Homme'
}.invert
=> "<select id=\"person_gender\" name=\"person[gender]\"><option
value=\"f\">Femme</option>\n<option value=\"h\">Homme</option></select>"

Simon
E4afabbb2fb6a2ea022df381b08b781e?d=identicon&s=25 Samoht Thomas (Guest)
on 2007-03-03 13:42
(Received via mailing list)
Et rebonjour après quelques jours, ma formation Ruby On Rails est
décidemment trop distillée dans le temps!

Pour en revenir au sujet, j'ai l'erreur suivante:

wrong argument type Symbol (expected Module)

Avec le code suivant:

13:
14: <p><label for="gender">H/F?</label><br/>
15: <%= select 'person', 'gender', {:f => 'Femme', :h => 'Homme'
}.invert %></p>
16:

Je ne vois pas du tout le rapport avec un "Module"...enfin je ne sais
pas
trop...quelqu'un a une idée?

Thomas
669e19951b848d1b0dac78655e34c2a4?d=identicon&s=25 Simon Pasquier (Guest)
on 2007-03-03 17:34
(Received via mailing list)
Tu pourrais nous fournir la pile d'exécution complète pour savoir quelle
méthode génère cette erreur?

Simon
A99870c1391c39da2089649745965bda?d=identicon&s=25 Jean-François Trân (Guest)
on 2007-03-03 18:19
(Received via mailing list)
Simon :
> Tu pourrais nous fournir la pile d'exécution complète pour savoir quelle
> méthode génère cette erreur?

Rien à rajouter par rapport à Simon, j'ai la même question.

Mais je viens seulement de percuter à propos de Samoht.
Coïncidence, une autre personne (Frédéric) a posté récemment
et a aussi une adresse électronique à l'envers. C'est une mode ?

   -- Jean-François.
E4afabbb2fb6a2ea022df381b08b781e?d=identicon&s=25 Samoht Thomas (Guest)
on 2007-03-04 02:18
(Received via mailing list)
Voici donc la trace:

c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.2/lib/action_view/helpers/form_options_helper.rb:116:in
`include?'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.2/lib/action_view/helpers/form_options_helper.rb:116:in
`options_for_select'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.2/lib/action_view/helpers/form_helper.rb:349:in
`inject'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.2/lib/action_view/helpers/form_options_helper.rb:114:in
`each'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.2/lib/action_view/helpers/form_options_helper.rb:114:in
`inject'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.2/lib/action_view/helpers/form_options_helper.rb:114:in
`options_for_select'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.2/lib/action_view/helpers/form_options_helper.rb:302:in
`to_select_tag'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.2/lib/action_view/helpers/form_options_helper.rb:66:in
`select'
#{RAILS_ROOT}/app/views/essei/_form_persons.rhtml:15:in
`_run_rhtml_47app47views47persons47_form_persons46rhtml'


Pour l'adresse à l'envers, cela remonte à bien longtemps... donc à la
limite
on pourra dire "c'était une mode"

Thomas
A99870c1391c39da2089649745965bda?d=identicon&s=25 Jean-François Trân (Guest)
on 2007-03-04 13:03
(Received via mailing list)
Samoht :
> Voici donc la trace:
>
> c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.2/lib/
> action_view/helpers/form_options_helper.rb:116:in `include?'

Pour une raison qui m'échappe encore, il semblerait que
ta version d'ActionView confonde include? avec include.
Aurais-tu édité et modifié form_options_helper.rb ?
Le fichier form_options_helper.rb corrompu d'une manière
ou d'une autre ?

Voici la somme md5 de form_options_helper.rb chez moi
(ActionPack 1.13.2)

ff1ce62913f5e3ba133936b1df7e51d1  form_options_helper.rb

Vérifie en particulier la ligne 116 de la méthode options_for_select.

D'autre part, avec :

<%= select 'person', 'gender', { 'f' => 'Femme', 'h' => 'Homme' }.invert
%></p>

tu devrais avoir l'erreur :

wrong argument type String (expected Module)

   -- Jean-François.
E4afabbb2fb6a2ea022df381b08b781e?d=identicon&s=25 Samoht Thomas (Guest)
on 2007-03-04 14:11
(Received via mailing list)
Interressant!

Je n'ai pas touché à form_options_helper.rb, cela dit il se pourrait
qu'il
soit corrompu...
J'ai la même version d'action pack que la tienne, et voici la ligne 116:

is_selected = ( (selected.respond_to?(:include?) &&
!selected.is_a?(String)
? selected.include?(element.last) : element.last == selected))

J'ai peu d'expérience que j'ai en ruby, cela dit je trouve cette
affectation
très interressante! un peu barbare avec plusieurs if...then...else sous
forme ? : imbriqués.
Apparement :include est considiré comme un symbole "(:include?)", tandis
que
c'est une méthode ailleurs "selected.include".
Bref, c'est bien pédagogique tout ça...!

Toutes explications sont les bien venues

Thomas
E4afabbb2fb6a2ea022df381b08b781e?d=identicon&s=25 Samoht Thomas (Guest)
on 2007-03-04 14:16
(Received via mailing list)
erratum, il n'y qu'un seul test ? : ... le reste sont des noms de
méthodes
de test contenant "?"

Thomas (qui admire de plus en plus ruby)
91eb330fb36d1e03c856574dfb77d2bc?d=identicon&s=25 Thibaut Barrère (thbar)
on 2007-03-04 14:22
(Received via mailing list)
Hello,

(1.13.2<http://dev.rubyonrails.org/browser/tags/rel_1-2-2/...)
on a:

116:            is_selected = ( (selected.respond_to?(:include?) &&
!selected.is_a?(String) ? selected.include?(element.last) : element.last
==
selected) )

pour une raison à déterminer, dans ton contexte le paramètre selected
semble
être une instance de Module (qui a une methode include?, qui attend un
module en paramètre, d'où probablement le 'wrong argument type Symbol'
lorsque selected.include? est appelé, vu que element.last doit être un
symbole ici).

Il faudrait voir pourquoi selected est un module ici (si c'est bien le
cas!).

Tu peux commencer par placer un breakpoint juste au dessus pour voir ce
que
contient selected (ou bien placer un throw selected).
E4afabbb2fb6a2ea022df381b08b781e?d=identicon&s=25 Samoht Thomas (Guest)
on 2007-03-04 14:59
(Received via mailing list)
J'ai trouvé.

J'ai voulu simplifié ma question alors j'ai traduit mon problème en le
ramenant au choix du sexe d'une personne, donc objet "Person" et
"Gender"
avec "homme" ou "femme".....ERREUR de ma part!

Car dans mon cas j'utilise autre chose.
En effet la liste select s'applique sur un objet "Logement" et sur le
paramètre "type" qui peut être "T1", "T2", etc...or apparement, "type"
est
un mot réservé qui a semé l'embrouille dans mon code.
J'ai renomé dans ma table "type" par "type_logement" et tout est rentré
dans
l'ordre.

Avis aux experts qui sauront le pourquoi du comment!

Pour ma part, milles excuses j'aurais du citer l'exemple réel!

Pour les autres, la morale de cette histoire est qu'il faut faire
attention
aux noms de symboles que l'on donne dans notre code....ils pourraient
être
réservés à Ruby ou Rails.

Thomas
A99870c1391c39da2089649745965bda?d=identicon&s=25 Jean-François Trân (Guest)
on 2007-03-04 17:16
(Received via mailing list)
Samoht :

> J'ai trouvé.
>
> J'ai voulu simplifié ma question alors j'ai traduit mon problème en le
> ramenant au choix du sexe d'une personne, donc objet "Person" et "Gender"
> avec "homme" ou "femme".....ERREUR de ma part!

Je ne comprends pas. ça voudrait dire que ce code :

<%= select 'person', 'gender', {:f => 'Femme', :h => 'Homme' }.invert %>

devrait marcher chez toi.

> Car dans mon cas j'utilise autre chose.
> En effet la liste select s'applique sur un objet "Logement" et
> sur le paramètre "type" qui peut être "T1", "T2", etc...or apparement,
> "type" est un mot réservé qui a semé l'embrouille dans mon code.
> J'ai renomé dans ma table "type" par "type_logement" et tout est
> rentré dans l'ordre.

Oui, il ne faut pas utiliser type et en plus si on fait du STI (single
table
inheritance), Active Record se sert de ce nom.

> Avis aux experts qui sauront le pourquoi du comment!

Voilà comment j'explique les choses :

<%= select 'logement', 'type', { 'T1' => ... } %>

ActionView (AV) à un moment a besoin de déterminer la valeur actuelle
du type de ta variable d'instance @logement. ça revient à faire un
@logement.type. Or, au lieu de retourner l'attribut de la colonne 'type'
de
ta table logements, il appelle Object#type c'est à dire Object#class,
méthodes héritées par ton objet Logement, donc ça retourne la
classe Logement.

Quand options_for_select est appelée, l'argument de la méthode
selected vaut Logement (la classe) (et non 'T1' ou 'T2').

On arrive à la ligne 116 :

is_selected = ( ( selected.respond_to?(:include?) &&
!selected.is_a?(String) ? selected.include?(element.last) :
element.last == selected))

on a selected = Logement, est-ce que Logement a une méthode d'instance
include?, oui car une Classe est un Module, donc Logement hérite de
Module#include? qui, comme l'a remarqué Thibaut réclame un Module en
argument.

!selected.is_a?(String) ? selected n'est pas une chaîne de caractères,
c'est une classe donc finalement le code :

selected.include?(element.last)

est invoqué et boum. qu'element.last soit une String ou un Symbol,
ça plante.

options_for_select fait du Ducktyping, il se dit, j'ai besoin de
savoir si selected est une collection (Hash, Array, classe
énumerable...) en mettant de côté le cas particulier de String
qui peut être vu comme une collection de caractères ou parce
que String#include? dit si une sous-chaîne est présente.
Or Class (via Module) a aussi une méthode d'instance
include? pour vérifier si un module est inclus dans une classe
(ou un module).

Autres remarques :

> J'ai peu d'expérience que j'ai en ruby, cela dit je trouve cette
> affectation très interressante! un peu barbare avec plusieurs
> if...then...else sous forme ? : imbriqués.

Je trouve l'utilisation de l'opérateur ternaire ? : moins
appropriéequand la ligne de code devient trop longue.

Je préfère l'écriture (que certains peuvent détester) :

is_selected = if selected.respond_to?(:include?) &&
!selected.is_a?(String)
                       selected.include?(element.last)
                    else
                       element.last == selected
                    end

plus claire. (éviter de répéter la lvalue c'est DRY :-) )

> Apparement :include est considiré comme un symbole "(:include?)",

ouais mon diagnostic n'était pas complètement juste, finalement
il n'y pas de confusion entre des méthodes include et include?

Rq : si tu fais include :MonModule au lieu de include MonModule,
tu as la même erreur :

TypeError: wrong argument type Symbol (expected Module)

- La convention pour une méthode qui retourne true ou false
c'est de la terminer par un point d'interrogation, tu trouveras
ça très pratique et très lisible :

if mon_objet.is_a?(String)
if current_user.admin?

Une autre convention (convention Ruby) est pour les
méthodes qui modifie l'objet ou les méthodes dangereuses,
consiste à mettre un point d'exclamation :

my_string.strip!

- Ruby repose sur le passage de messages. C'est à dire
que tu envoies un message à un objet (le receveur) avec
éventuellement des paramètres pour invoquer une méthode.

mon_objet.send(:nom_de_la_methode, argument_un, argument_deux...)

revient à faire :
mon_objet.nom_de_la_methode(argument_un, argument_deux...)

Pour select, la signature est :
select(object, method, choices, options = {}, html_options = {})

et AV va se servir de l'argument method pour faire un passage
de message à @logement.

- enfin pour les Symboles, :foo et :foo? sont deux objets Symbol
bien distincts.

Pour un passage de paramètres, les méthodes invoquées
ne seront pas les mêmes :

ga.send :buzomeu et ga.send :buzomeu?

sont bien différents.

> Pour ma part, milles excuses j'aurais du citer l'exemple réel!

Clair. Je n'arrivais pas à reproduire le bug.

> Pour les autres, la morale de cette histoire est qu'il faut faire
> attention aux noms de symboles que l'on donne dans notre
> code....ils pourraient être réservés à Ruby ou Rails.

Un problème assez similaire est le nom des actions pour
un contrôleur. Comme ton contrôleur est un objet, il hérite
des méthodes d'instance d'Object. Ainsi par exemple,
appeler une action 'display' ne marchera pas.


Pour fini, Simon a bien fait de te demander le traceback...

Car c'est la victoire de Samoht trace.

   -- Jean-François (en forme).
E4afabbb2fb6a2ea022df381b08b781e?d=identicon&s=25 Samoht Thomas (Guest)
on 2007-03-04 17:35
(Received via mailing list)
rires!

Excellentes explications...comme quoi sur un petit problèmes on peut en
apprendre beaucoup.

Pour info le code:

<%= select 'person', 'gender', {:f => 'Femme', :h => 'Homme' }.invert %>

fonctionnait cependant je n'avais cop/col que la partie {:f => 'Femme',
:h
=> 'Homme' }.invert (pensant que le problème venait de là...)

Mes chers amis, je vous remercie!

Thomas
This topic is locked and can not be replied to.