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
-~----------~----~----~----~------~----~------~--~---

Reply via email to