L'habitude du HAML j'ai oublié le end... ça donne bien : <% Role.all.each do |role| %> <%= check_box_tag 'user[role_ids][]', role.id, @user.roles.include?(role) %> <%= role.name %> <% end %>
<%= hidden_field_tag 'user[role_ids][]', '' %> 2010/12/15 Nicolas Blanco <[email protected]>: > Cette question revient souvent. Donc je me la sauvegarde pour la > prochaine fois :). > > En gros la question c'est : comment mapper un formulaire sur du > has_and_belongs_to_many ou has_many :through. Par exemple User > has_and_belongs_to_many :roles. Je veux pouvoir afficher l'édition du > user avec la liste de tous les roles et des cases à cocher. > > Y a une manière automatique de le faire qui ne nécessite aucune > modification ou traitement dans le controleur. > > Une relation habtm ou hmt rajoute une méthode supplémentaire dans > l'instance du modèle dont le nom est le nom de la relation au > singulier suivi de _ids, donc dans l'exemple : role_ids. Cette méthode > renvoie la liste des ids des roles rattachés au user en question. Et > il y a aussi un setter ! > > Cela veut dire qu'on peut directement setter les roles en envoyant à > cette méthode un un tableau contenant les ids des roles. Donc comment > faire au niveau de la vue et du form... Comme cela : > > <% Role.all.each do |role| %> > <%= check_box_tag 'user[role_ids][]', role.id, @user.roles.include?(role) %> > <%= role.name %> > > <%= hidden_field_tag 'user[role_ids][]', '' %> > > Et c'est tout. Dans le controleur on garde le traitement habituel CRUD > (du style User.new(params[:user]) ou > @user.update_attributes(params[:user])... > > Pourquoi ce hidden_field_tag avec une chaine vide a la fin ? c'est > juste une bidouille pour que si aucune case n'est cochée, que Rails > reçoit un tableau vide, et donc vide correctement la liste d'ids. > Sinon, l'attribut role_ids n'existera pas dans les paramètres et rien > ne changera au niveau de la liste. > > Nicolas. > > 2010/12/14 Michel Belleville <[email protected]>: >> Si tu regarde la doc sur check_box_tag : >> http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html >> >> Tu constate que sa signature est : >> check_box_tag(name, value = "1", checked = false, options = {}) >> >> Donc le 3° arguments checked attend un booléen, par défaut false. Or en >> Ruby, quand on essaye d'utiliser n'importe quelle valeur à part false ou nil >> en tant que booléen, ça vaut true. Toi tu fais : >> user.profils.map {|p| p == profil} >> >> map renvoie un Array de valeurs renvoyées par le bloc de code que tu lui >> donne en itérant sur les valeurs de l'énumération, donc ici au lieu d'un >> booléen tu envoie un tableau, qui vaut true une fois converti en booléen. >> >> Peut-être que tu devrais utiliser la méthode any? au lieu de map ; any? >> itère sur chaque élément de l'énumération (comme map) jusqu'à trouver un >> élément pour lequel la valeur de retour de l'itérateur n'est pas false ou >> nil ; si elle en trouve un elle renvoie true, sinon elle itère sur tous les >> éléments et renvoie false après le dernier. >> >> En espérant que ça te débloque... >> >> Michel Belleville >> >> >> 2010/12/14 arnaud <[email protected]> >>> >>> Bonjour, >>> >>> j'ai besoin d'une petite appli web très simple donc j'en profite pour >>> tester rails3. >>> >>> En gros, j'ai une liste d'utilisateur et de profil. >>> Un utilisateur peut avoir 0 ou plusieurs profils et vice-versa. >>> >>> Je souhaite créer un tableau avec en ligne mes utilisateurs et en >>> colonne mes profils. >>> Pas de problème jusqu'ici. >>> >>> Là où ça pêche, c'est que je veux une case à cocher pour chaque droits >>> et que la case soit cochée ou pas si l'utilisateur a le profil ou pas. >>> Toutes mes checkbox sont cochées ! >>> >>> Voyez-vous d'où vient mon erreur ? >>> >>> D'avance merci! >>> >>> Voila mon code : >>> >>> <table> >>> <tr> >>> <th>Firstname</th> >>> <th>Lastname</th> >>> <th>Login</th> >>> <% @profils.each do |profil| %> >>> <th><%= profil.name %></th> >>> <% end %> >>> <th></th> >>> <th></th> >>> <th></th> >>> </tr> >>> >>> <% @users.each do |user| %> >>> <tr> >>> <td><%= user.firstname %></td> >>> <td><%= user.lastname %></td> >>> <td><%= user.login %></td> >>> <% @profils.each do |profil| %> >>> <td><%= check_box_tag("profil_#{user.id}_#{profil.id}" , "yes", >>> user.profils.map{|p| p == profil}) %></td> >>> <% end %> >>> <td><%= link_to 'Show', user %></td> >>> <td><%= link_to 'Edit', edit_user_path(user) %></td> >>> <td><%= link_to 'Destroy', user, :confirm => 'Are you >>> sure?', :method => :delete %></td> >>> </tr> >>> <% end %> >>> </table> >>> >>> -- >>> Vous avez reçu ce message, car vous êtes abonné au groupe "Railsfrance" de >>> Google Groups. >>> Pour transmettre des messages à ce groupe, envoyez un e-mail à l'adresse >>> [email protected] >>> Pour résilier votre abonnement envoyez un e-mail à l'adresse >>> [email protected] >> >> -- >> Vous avez reçu ce message, car vous êtes abonné au groupe "Railsfrance" de >> Google Groups. >> Pour transmettre des messages à ce groupe, envoyez un e-mail à l'adresse >> [email protected] >> Pour résilier votre abonnement envoyez un e-mail à l'adresse >> [email protected] > > > > -- > Nicolas Blanco, Web developper > > http://www.nicolasblanco.fr > Jabber/GoogleTalk : [email protected] > Twitter : http://twitter.com/slainer68 > Github : http://github.com/slainer68 > Skype : slainer68 > -- Nicolas Blanco, Web developper http://www.nicolasblanco.fr Jabber/GoogleTalk : [email protected] Twitter : http://twitter.com/slainer68 Github : http://github.com/slainer68 Skype : slainer68 -- Vous avez reçu ce message, car vous êtes abonné au groupe "Railsfrance" de Google Groups. Pour transmettre des messages à ce groupe, envoyez un e-mail à l'adresse [email protected] Pour résilier votre abonnement envoyez un e-mail à l'adresse [email protected]
