On Oct 21, 2009, at 2:50 AM, Leonardo Frittelli wrote:
> Fellow "Hoboers",
>
> I have a doubt about the member_class attribute in collections
> I have noticed that some rapid tags such as <count> use this method
> to determine labels that will be displayed alongside their output
> (e.g: "3 Items" for <count:items>)
>
> Now, say a model BlogPost declares a has_many :blog_comments, then
> whenever I do a post.blog_comments I will get an Array that will
> have a "member_class" attribute set to BlogComment. This is somehow
> done automagically for me by Hobo (I presume).
To be nitpicky, what you get back is an AssociationCollection that
does a really good job of pretending to be an Array. (see the AR
source for details)
> The problem is that I now would like to have a new accessor method,
> that would return all comments posted by a certain user:
>
> def user_comments(user)
> blog_comments.collect { |comment| comment.user == user }.compact
> end
>
> I have noticed that the magic no longer works for me here, so if I
> want this collection to work with rapid tags, then I will need to do
> something like:
>
> def user_comments(user)
> coll=blog_comments.collect { |comment| comment.user ==
> user }.compact
> coll.member_class = BlogComment
> coll
> end
>
> Am I doing anything wrong here? Is there a better way to achieve
> this end?
It's even more important in Hobo than in plain Rails to avoid post-
find filtering like this - in plain Rails, all it costs you is
performance (instantiating too many records). But in Hobo, as you've
noted, the magic tends to fall off.
Assuming you've got a standard model setup (Blog has_many
BlogComments, BlogComment belongs_to User), you can use a named scope
like this (on BlogComment):
named_scope :for_user, lambda { |u| { :conditions => { :user_id =>
u.id } }
Usage:
@blog_post.blog_comments.for_user(@some_user)
This has two advantages:
- as Bryan pointed out, it doesn't load records you don't want. The
underlying SQL will incorporate the user_id condition directly.
- it returns a real proxy object instead of a bare Array. This means
you can further limit/order/paginate/etc. the results:
@blog_post.blog_comments.for_user(@some_user).scoped(:order =>
'some_field').paginate
(OK, that's a little much for one line, but you get the idea).
--Matt Jones
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Hobo
Users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/hobousers?hl=en
-~----------~----~----~----~------~----~------~--~---