Wrap single object in array for FullCalendar in Rails

199 Views Asked by At

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?

1

There are 1 best solutions below

3
edariedl On BEST ANSWER

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.