Search code examples
ruby-on-railsjsonrubyneo4jgraph-databases

How to generate GraphJSON from Neo4j::ActiveModel using jbuilder


A frontend library used to render graph data in the browser alchemy.js requires data in the GraphJSON format, which mainly consists of a nodes and edges top-level keys.

Consider a graph of Services that can have dependencies (and thus dependent_services):

class Service
  include Neo4j::ActiveNode
  has_many :out, :dependencies, type: :DEPENDS_ON, model_class: :Service
  has_many :in, :dependent_services, origin: :dependencies, model_class: :Service
end

Retrieving the node data in the jbuilder template works like a charm:

nodes = ([service] + service.dependencies + service.dependent_services).uniq
json.nodes nodes do |node|
  json.id node.id
  json.name node.name
  json.type node.class.to_s
  json.url "#{url_for(node)}.json"
end

Is there a neat way to retrieve the list of edges (Relationships) between the nodes?


Solution

  • I found a relatively elegant solution, so just in case anyone else is looking for this:

    # Collect all relations into flat array
    relations = [service.dependencies, service.dependent_services].map {|r| r.rels}.flatten
    # Collect relation into edges array
    json.edges relations.map do |edge|
      json.source edge.start_node_id.to_s.to_i
      json.target edge.end_node_id.to_s.to_i
      json.caption edge.type
    end
    

    Of course the second part is jbuilder specific, but most importantly theres the .rels property that holds a list of all outgoing/incoming relations.

    I'm using the neo4j gem @9.0.7 for this, documentation can be found here: https://github.com/neo4jrb/neo4j-core/wiki/Relationship