Bonjour à tous
Bon j'ai conscience que le titre de mon message puisse sembler bizarre, et il est d'ailleurs sans doute faux dans l'absolu... mais je n'y comprends plus rien, donc je viens chercher un peu de secours.
Situation : j'ai une appli Rails qui utilise acts_as_commentable et acts_as_bookmarkable sur un même modèle Diagram. Pas de souci pour utiliser ces deux plugins d'une manière générale.
Maintenant, dans la vue show de mon Diagram, j'aimerais afficher à la fois les commentaires et une ligne informative par bookmark, du genre "Machin a ajouté ce diagramme à ses favoris".
Dans un controller, j'ai une action qui fait ce job:
Donc en gros: je récupère les commentaires, j'ajoute les bookmarks à la collection si le modèle peut être "bookmarké", puis je trie le tout par date de création.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 # Get bookmarked class from params and fetch the wanted instance model_class = Kernel.const_get(params[:commentable][:type].capitalize) instance = model_class.find params[:commentable][:id] report_error("Cannot find " << model_class.to_s << " with id " << params[:commentable][:id].to_s) if instance.nil? @comments = instance.comments # Include bookmarks if model is bookmarkable, and sort bookmarks and comments all together if BookmarksController::BOOKMARKABLE_MODELS.include?(model_class.to_s) @comments += instance.bookmarks @comments = @comments.sort_by {|obj| obj.created_at} end
J'ai ensuite une vue et quelques partials qui se chargent de l'affichage :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 ## Ficher index.html.haml = render :partial => "comment", :collection => @comments
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 ## Fichier _comment.html.haml (appelé pour chaque élément de @comments donc) = debug comment = debug comment.user -# The 'comment' might be a bookmark. Handle it first. - if comment.instance_of?(Bookmark) .bookmark = render :partial => "/comments/comment_bookmark", :locals => { :bookmark => comment } - else .comment{:class => cycle("odd", "even")} = render :partial => "/comments/comment_content", :locals => { :comment => comment}Le problème se trouve dans ce dernier fichier, le partial qui sert à l'affichage de la ligne d'info d'un bookmark. J'obtiens l'erreur :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 ## Fichier _comment_bookmark.html.haml = image_tag "/images/iLight/icon.png" == #{bookmark.user.display_name} lit this diagram <small>(#{time_ago_in_words bookmark.created_at} ago)</small>
Déjà, je ne vois pas d'où il sort son appel à include?ActionView::TemplateError (You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.include?) on line #2 of app/views/comments/_comment_bookmark.html.haml:
1: = image_tag "/images/iLight/icon.png"
2: == #{bookmark.user.display_name} lit this diagram <small>(#{time_ago_in_words bookmark.created_at} ago)</small>
Un rapide test me montre que c'est l'appel bookmark.user.display_name qui cause l'exception. Un appel à n'importe quel attribut de bookmark.user, ou n'importe quelle méthode, causera la même erreur.
Toutefois, bookmark.user n'est pas nil !
Comme vous pouvez voir j'ai mis deux appels à debug dans _comment.html.haml.
Dans le cas d'un commentaire, ça me donne :
Dans le cas d'un bookmark, ça me donne :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 --- !ruby/object:Comment attributes: comment: pouet created_at: 2010-10-11 00:44:02 title: "" commentable_type: Diagram commentable_id: "29" updated_at: 2010-10-11 00:44:02 id: "41" user_id: "2" attributes_cache: created_at: 2010-10-11 00:44:02 Z --- !ruby/object:User attributes: created_at: 2010-05-23 18:31:02 activated_at: 2010-06-08 22:23:19 send_news: "1" remember_token_expires_at: updated_at: 2010-09-19 22:36:42 activation_code: old_email: id: "2" saved_once: "1" email_hash: 672585615_3008d2bf2e8e7f4455d48212f99a9343 remember_token: short_name: olance diagrams_count: "16" display_name: Olivier Lance attributes_cache: {}
La différence de formatage de l'objet User m'interpelle... d'autant que si je coupe le serveur, le relance (j'utilise Mongrel en développement) et refresh la page, le debug comment.user pour un bookmark aura la même tête que pour un comment. Et l'appel à display_name fonctionne alors. Mais seulement la première fois juste après le relancement du serveur. Si je refresh une nouvelle fois, ça prend la tête d'au-dessus, et l'appel plante. (je sais pas si je suis clair ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 --- !ruby/object:Bookmark attributes: bookmarkable_type: Diagram bookmarkable_id: "29" created_at: 2010-10-11 01:18:41 title: new items updated_at: 2010-10-11 01:18:41 id: "253" user_id: "2" attributes_cache: created_at: 2010-10-11 01:18:41 Z #<User id: 2, created_at: "2010-05-23 18:31:02", updated_at: "2010-09-19 22:36:42", remember_token: nil, remember_token_expires_at: nil, activation_code: nil, activated_at: "2010-06-08 22:23:19", email_hash: "672585615_3008d2bf2e8e7f4455d48212f99a9343", display_name: "Olivier Lance", short_name: "olance", send_news: true, saved_once: true, diagrams_count: 16, old_email: nil, changed_email: nil>)
Voilà voilà... j'ai essayé de debugger avec ruby-debug mais ça ne m'a rien donné de concluant, je n'arrive pas à breaker sur l'exception TemplateError ou NoMethodError...
Je viens de passer des heures là-dessus, je n'y comprends rien du tout et je n'ai pas beaucoup d'expérience dans la résolution de ce genre de souci. Donc si quelqu'un a une idée de solution ou de méthode pour dénicher le problème, je suis preneur !!
edit: j'ai oublié de préciser que j'utilise Ruby 1.8.7 et Rails 2.3.8
Olivier








)
Répondre avec citation

Partager