1
\$\begingroup\$

I use the gem act_as_votable to allow users to select categories they like. To get the categories a user likes:

 current_user.get_voted(Category)

These categories have children categories, and I need to find the posts in those children categories.

I use this line to do it:

@categories_posts = current_user.get_voted(Category).flat_map { |category| category.children.flat_map(&:posts)}.delete_if{ |post| post.status == "draft"}

But I noticed in my logs that this was doing way too much computation for this task.

Is there a way to make it lighter ?

asked Jul 10, 2016 at 9:20
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Some notes:

  • You should limit the lines to 80/100 chars.
  • When a call chain seems to include too much logic, move it to methods/class-methods of models.

As a first refactor, I'd implement Category#with_children and then write:

@categories_posts = current_user.
 get_voted(Category).
 flat_map(&:with_children).
 flat_map(&:posts).
 reject { |post| post.status == "draft" }

On a second refactor, it's nice to have relations instead of arrays as output. This way you can use scopes, paginators and such, even if you cannot directly use has_many here (because of the recursive category requirement):

categories = current_user.get_voted(Category).flat_map(&:with_children)
@categories_posts = Post.where(category: categories).published

That's to show the implementation, on the controller you should still have less logic, something like this: @categories_posts = current_user.posts_of_voted_categories.published.

answered Jul 12, 2016 at 19:07
\$\endgroup\$
2
  • \$\begingroup\$ Thanks for your input ! This indeed makes the code more readable, but does it make it more efficient ? \$\endgroup\$ Commented Jul 12, 2016 at 20:12
  • \$\begingroup\$ Updated, now it should be more efficient, it's using SQL from the category level. \$\endgroup\$ Commented Jul 13, 2016 at 7:25

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.