1

I am working on a neo4j rails project that involves a parent-child type relationship between nodes from the same model. Any child can have multiple parents. I would like to be able to create the parent-child relationships when I create a new child. How should I implement this? Currently, the app is set up to only create one parent-child relationship when the child is created.

# View for ...things/new
<div class="new-thing-form">
  <%= form_for(@thing) do |f| %>
    <%= f.text_field :name, placeholder: "Thing Name" %>
    <%= text_field_tag :parent, '', placeholder: "Parent Name" %>
    <%= f.submit "Create Thing" %>
  <% end %>
</div>

# Model for Thing
  class Thing 
    include Neo4j::ActiveNode

    property :name, type: String
    property :description, type: String


    has_many :out, :children_things, type: :PARENT_OF, model_class: :Thing
    has_many :in, :parent_things, model_class: :Thing, origin: :children_things

    validates_presence_of :name
  end

I've considered three possible solutions so far and am having trouble wrapping my head around them (I am new to web development so I apologize if this is basic stuff).

  1. Dynamically Add Fields

I've checked out Railscasts episode 196 and 197, however I am having trouble using "accepts_nested_attributes_for." Also, this is a relationship between nodes of the same model, so is there a way to add and remove fields without using nested attributes?

  1. Create a multiselect list

There are many posts on creating multiselect menus using Bootstrap and ActiveRecord. How should I implement these using Neo4j?

  1. Create ActiveRel for PARENT_OF relationship

Is there a way to create relationships through forms? If so, then is there a way to do that in conjunction with a nested_attributes method to create new PARENT_OF relationships when a child thing is created?

Sorry for the open-ended questions. I've been looking around for a couple of days now and would really appreciate some guidance, even if you can just point me in the right direction. Any advice would help. Thanks again.

1 Answers1

0

I've not previously used accepts_nested_attributes_for myself. I know that we've discussed it in the past, but I don't recall if we ever implemented support. There is a discussion on this GitHub issue. Also feel free to stop by our Gitter chat room.

You might not need it, though. You should be able to create relationships on nodes via controller params for either has_one or has_many. Such as:

Thing.create(name: params[:thing][:name], parent_things: params[:thing][:parents])

The params[:thing][:parents] should be an array of node IDs. Then when the node is created all of the relationships should be created as well.

Of course you can also just pass in all of the params for thing:

Thing.create(name: params[:thing])

But depending on your security situation you probably want to use Rails' strong parameters to make sure people don't pass in things that they shouldn't.

EDIT:

Some view code in response to your comment:

<div class="new-thing-form">
  <%= form_for(@thing) do |f| %>
    <%= f.text_field :name, placeholder: "Thing Name" %>
    <%= text_field_tag 'thing[parent][]', '', placeholder: "Parent Name" %>
    <%= text_field_tag 'thing[parent][]', '', placeholder: "Parent Name" %>
    <%= f.submit "Create Thing" %>
  <% end %>
</div>

The f.text_field tag (I believe) will automatically make it's field name thing[name], so the text_field_tag is going along with that. By putting the [] at the end you're saying that this is going to be an array of parents. So the params Hash should be something like {thing: {name: 'Foo', parents: ['id1', 'id2']}}

Brian Underwood
  • 10,746
  • 1
  • 22
  • 34
  • Brian, thanks for the response. I'm still confused about how I should format the view so that the user can input an indefinite number of "parent_things" upon creation of a new node. How can I create a form that will allow for that? – Nimayi Dixit Mar 07 '16 at 19:50
  • Thanks, Brian. That did create an array in the params hash for parent id's. On the front end, each tag was still only a single text field. I've adjusted the app's workflow so that creating a "thing" and adding "parent_things" are handled by two separate views. Thanks for the tip, it's very useful to know how to create arrays like that in the params hash. – Nimayi Dixit Mar 10 '16 at 16:43
  • Right, I guess I didn't think to much about the fact that those are text fields. One thing that I often do is make a "select" field which allows you to show names but send IDs back to the server. If you're doing it without any sort of JS library which would be rendering a template, you might store a hidden select field off to the side and then just `clone()` it into place when you want to add a new one. – Brian Underwood Mar 11 '16 at 07:43
  • That's a pretty interesting idea. Right now it's functioning ok with the two separate views and I don't want to spend too much time trying to make this one aspect perfect. You mentioned rendering with JS libraries - I'm thinking about trying to overlay an _add_parent_form partial on the DOM when I get to the front-end stuff (I think it's possible with jQuery). If that doesn't work, though, I'll definitely give the clone() method a shot. Thanks again for all your help, btw. I'm sure you guys are busy with a lot of things, so I really appreciate it. – Nimayi Dixit Mar 11 '16 at 12:33