Search code examples
ruby-on-railsjsonjbuilder

Including other one jbuilder template in another


Consider the following show.json.jbuilder template:

json.user do |json|
    json.extract! @user, :id, :username, :email, :created_at, :avatar
end

json.policies do |json|
    json.array!(@policies) do |policy|
        json.extract! policy, :id, :title, :cached_votes_score
    end
end

json.liked do |json|
    json.array!(@liked) do |policy|
        json.extract! policy, :id, :title, :cached_votes_score
    end
end

json.disliked do |json|
    json.array!(@disliked) do |policy|
        json.extract! policy, :id, :title, :cached_votes_score
    end
end

Would it be possible to split those up into four different templates, and then just include them in the show template? Something like:

include template_user
include template_policies
include template_liked
include template_disliked

If this is not possible, what alternatives exist for creating more modular jbuilder code? I find my jbuilder code very un-DRY.


Solution

  • Yes. Is possible. Split your files like:

    _user.json.jbuilder

    json.user do |json| json.extract! @user, :id, :username, :email, :created_at, :avatar end

    _policies.json.jbuilder

    json.policies do |json| json.array!(@policies) do |policy| json.extract! policy, :id, :title, :cached_votes_score end end

    _liked.json.jbuilder

    json.liked do |json| json.array!(@liked) do |policy| json.extract! policy, :id, :title, :cached_votes_score end end

    _disliked.json.jbuilder

    json.disliked do |json| json.array!(@disliked) do |policy| json.extract! policy, :id, :title, :cached_votes_score end end

    and then you can simply join them with:

    show.json.jbuilder

    json.partial! 'user' json.partial! 'policies' json.partial! 'liked' json.partial! 'disliked'

    But I would suggest to improve them a little bit and write them using local variables and so:

    _user.json.jbuilder

    json.user do |json| json.extract! user, :id, :username, :email, :created_at, :avatar end

    and you include it passing the user as an argument:

    json.partial! 'user', user: @user