Hi,
I’ve got a problem on which I’ve spent many hours, and I can’t get a
clue on what is happening… I hope someone here will be able to help
me.
Here is the situation : my Rails app uses acts_as_commentable and
acts_as_bookmarkable on a Diagram model. Everything’s working OK
individually: I can create a comment on a Diagram, bookmark it, and so
on.
Now, I’d like to have a list in the “show” view of a diagram, which
shows all comments and a line per bookmark saying something like “John
added this diagram as a favorite”.
I’ve got an action in a comments controller fetching the data:
# 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
So I fetch all comments for the commentable model (Diagram in my
example), then add the bookmarks to the collection and sort everything
by creation date. This works fine.
I’m displaying this list with a view and some partials:
index.html.haml
= render :partial => “comment”, :collection => @comments
_comment.html.haml (called for each item in @comments)
= 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}
_comment_bookmark.html.haml
= image_tag “/images/iLight/icon.png”
== #{bookmark.user.display_name} lit this diagram
(#{time_ago_in_words bookmark.created_at} ago)
The problem happens in this last file, when calling
bookmark.user.display_name. It raises a Template error:
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
(#{time_ago_in_words bookmark.created_at} ago)
First thing, I just can’t see where does this “include?” call comes from
:
I’ve tried calling other attributes/methods on bookmark.user and never
get any error. If I just try to output bookmark.user it works and
displays “#”.
As you can see, I’ve got two debug calls in my view.
When the partial is called for a Comment, debug displays the following:
— !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 L.
attributes_cache: {}
When it’s a Bookmark object, it displays:
— !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>
I’m suspicious about this difference in the User object output.
When I restart my dev server (Mongrel) and refresh the page, the output
for the Bookmark’s user looks exactly like the comments ones, and
bookmark.user.display_name doesn’t raise any error.
Then, if I refresh the page again, I get the above output and the
TemplateError exception.
I’ve tried to debug using ruby-debug, but couldn’t succeed in breaking
on TemplateError or NoMethodError exceptions…
I’ve just spent hours on this, I really don’t get and don’t have a lot
of experience in dealing with that kind of issues…
I’d really appreciate if someone had an idea on how to fix this or at
least to track the bug down!
By the way, I’m using Rails 2.3.8 with Ruby 1.8.7
Thanks a lot for reading this and for any help!
Olivier
Olivier