0

Can anyone offer some advice as to what the "best" way to include nested objects/relations in a JSON response that you want to filter?

In the simple example below, say the model Comment has a soft delete flag is_deleted = true, I want to only include comments that have is_deleted = false. What's the best way to accomplish this?

posts = Post.all
render json: posts.to_json(:include => [:comments])

2 Answers 2

2

I could come up with a simple solution. In Post, you can scope the deleted comments out from the results, like this:

has_many :comments, -> { is_deleted: false }

This will return only those comments, which are not deleted. And then, your existing JSON code will work fine.

Edit 1:

This solution is as per our discussion in comments.

Create a convenience method in Post. This will return all the comments which are not deleted.

def visible_comments
  comments.where(is_deleted: false)
end

Then, you can change your render method as follows:

render json: posts.to_json(:include => [:visible_comments])

This will call the visible_comments method of Post and will include the results returned by that method only.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the answer. I did try this, but we also don't want that scope to apply all the time since we do display comments that have been deleted to our "admins".
In that case, you can create a custom scope e.g. scope :visible_comments, -> { comments.where(is_deleted: false) }, and include this scope in your JSON rendering.
Do you know what the syntax is for including a custom scope?
@TimS -- My bad! You don't need to create a custom scope. A convenience method will do the trick. See my updated answer.
That worked, - thanks a ton! I don't suppose there's a way to rename or alias the convenience method is there? I couldn't find anything, but something like :include => [:visible_comments as :comments] ?
0

Edit your modal

class Post < ActiveRecord::Base  

   def as_json(_options = {})
    super only: [:id, :title],
          include: {
            comments: {
              only: [:id, :comment_fieds]
            }
   end
end


class Comment < ActiveRecord::Base
  default_scope { where is_deleted: false }
end

You can add comments and post field in only: [.....] that you want to include in response

posts = Post.all
render json: posts

1 Comment

Thanks for the answer. I did try this, but we also don't want that scope to apply all the time since we do display comments that have been deleted to our "admins".

Your Answer

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.