ruby-on-railsjbuilder

Wrap single object in array for FullCalendar in Rails


I have a Rails model instance that I need to use jBuilder to convert to json. My code is currently:

json.name @trip.name
json.title @trip.name
json.start_date @trip.start_date
json.end_date @trip.end_date
json.start @trip.start_date
json.end @trip.end_date
json.allDay true
if ActiveRecord::Type::Boolean.new.cast(params[:show_visits]) == true
    json.visits @trip.visits.each do |visit|
        json.date visit.date.to_date.day.ordinalize + " " + visit.date.to_date.strftime("%b %Y")
        json.park visit.park.name
        json.first_on_trip visit.first_on_trip?
        json.last_on_trip visit.last_on_trip?
        # json.gallery visit.has_gallery? ? url_for(visit.album) : false
        if visit.park.has_location?
            json.park_lat visit.park.lat
            json.park_lng visit.park.lng
        end
    end
end

Basically, I need to wrap that in an array as that is what FullCalendar is expecting. I have this json file being called elsewhere so the array part needs to be optional too.

How can I use jBuilder to add a wrapping array to my output?


Solution

  • You should probably split your code into three files. First create a partial from your code above, you could name it eg _trip.json.jbuilder:

    json.name trip.name
    json.title trip.name
    json.start_date trip.start_date
    json.end_date trip.end_date
    json.start trip.start_date
    json.end trip.end_date
    json.allDay true
    if ActiveRecord::Type::Boolean.new.cast(params[:show_visits]) == true
        json.visits trip.visits.each do |visit|
            json.date visit.date.to_date.day.ordinalize + " " + visit.date.to_date.strftime("%b %Y")
            json.park visit.park.name
            json.first_on_trip visit.first_on_trip?
            json.last_on_trip visit.last_on_trip?
            # json.gallery visit.has_gallery? ? url_for(visit.album) : false
            if visit.park.has_location?
                json.park_lat visit.park.lat
                json.park_lng visit.park.lng
            end
        end
    end
    

    I also removed instance variable and replaced it with local one. Now you can create two views where you use this partial, one for the calendar and second for the other place:

    calendar.json.jbuilder

    json.array! [@trip] do |trip|
      json.partial! "path/to/trip", locals: { trip: trip }
    end
    

    other_place.json.jbuilder will be even easier:

    json.partial! "path/to/trip", locals: { trip: @trip }
    

    For the exact partial rendering code please see the jBuilder documentation. It may be a bit more complicated or even easier based on location of these files in the views.

    You could probably use instance variable directly in the partial, but this solution makes it a little bit more general and therefore the partial can be used in more different contexts.