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]

Répondre à