0

Problem: dependent destroy ain't happening with this setup! Help me spot the problem!

The event has questions, and each question can have many answers

event.rb

  include Neo4j::ActiveNode

  has_many :both, :users, model_class: 'User', rel_class: 'Invite'
  has_many :in, :event_questions, type: 'questions_of', dependent: :destroy

eventquestion.rb

  include Neo4j::ActiveNode

  has_one :out, :event, origin: :event_questions
  has_many :in, :event_answers, type: 'answers_of', dependent: :destroy

eventanswer.rb

  include Neo4j::ActiveNode

  has_one :out, :event_question, origin: :event_answers

event_controller.rb

   if event.destroy
        location.destroy
        flash[:success] = "Event deleted"
    else

I'm on the neo4j master branch.

gemlock indicates

  neo4j (4.1.0)
  active_attr (~> 0.8)
  activemodel (~> 4)
  activesupport (~> 4)
  neo4j-core (~> 4.0.0)
  orm_adapter (~> 0.5.0)
  railties (~> 4)

I don't think this is entirely relevant but maybe i'm crazy.. but I do have a

before_action :admin_or_owner, only: [:destroy] 

on my eventquestion.rb and eventanswer.rb

however, i'm not calling the controller method destroy in my dependent destroy so this shouldn't matter?

Clam
  • 935
  • 1
  • 12
  • 24
  • How are you calling the destroy? Just `event.destroy`? – Brian Underwood Jan 13 '15 at 07:28
  • Also, the language of the relationship types seems a little confusing. I would expect the `answers_of` and `questions_of` to be in the other direction. Or alternatively you could have something like `(event)-[:has_question]->(question)` and `(question)<-[:answers]-(answer)` – Brian Underwood Jan 13 '15 at 07:32
  • yeah it's just an if else case. just gave the first part as the example. i always thought in, sorta like a belongs to association, event_question belongs to event, event_answers belong to event_questions – Clam Jan 13 '15 at 10:00
  • It might not be right, but I often think about relationship types as a sort of sentence read in the direction of the arrow – Brian Underwood Jan 13 '15 at 11:01
  • I've sent a message to my colleague on the neo4j gem who did this work recently to see if he could take a look at the question – Brian Underwood Jan 13 '15 at 11:17

1 Answers1

1

I think there's something else happening in your app because as described, using the code provided, everything works exactly as I expect. I built this section of your app using the code provided.

class Event
  include Neo4j::ActiveNode
    has_many :both, :users, model_class: 'User', rel_class: 'Invite'
    has_many :in, :event_questions, type: 'questions_of', dependent: :destroy
end

class User
  include Neo4j::ActiveNode
  has_many :both, :events, rel_class: 'Invite'
end

class Invite
  include Neo4j::ActiveRel
  from_class User
  to_class Event

  type 'INVITED_TO'
end

class EventQuestion
  include Neo4j::ActiveNode
  has_one :out, :event, origin: :event_questions
  has_many :in, :event_answers, type: 'answers_of', dependent: :destroy
end


class EventAnswer
  include Neo4j::ActiveNode
  has_one :out, :event_question, origin: :event_answers

end

Here, I create two events, three questions, three answers and wire them together. You can see that destroying the event destroys its questions which, in turn, destroy their answers.

e1 = Event.create
 => #<Event> 
2.2.0 :052 > e2 = Event.create
 => #<Event> 
2.2.0 :053 > q1 = EventQuestion.create
 => #<EventQuestion> 
2.2.0 :054 > q2 = EventQuestion.create
 => #<EventQuestion> 
2.2.0 :055 > q3 = EventQuestion.create
 => #<EventQuestion> 
2.2.0 :056 > a1 = EventAnswer.create
 => #<EventAnswer> 
2.2.0 :057 > a2 = EventAnswer.create
 => #<EventAnswer> 
2.2.0 :058 > a3 = EventAnswer.create
 => #<EventAnswer> 
2.2.0 :059 > 
2.2.0 :060 >   e1.event_questions << q1
 CYPHER 4ms MATCH (start:`Event`), (end:`EventQuestion`) WHERE ID(start) = {start_id} AND ID(end) = {end_id} CREATE start<-[rel0:`questions_of`]-end | {:start_id=>23, :end_id=>25}
 => #<Neo4j::ActiveNode::Query::QueryProxy:0x007fc05e0f3248 @model=EventQuestion, @association=#<Neo4j::ActiveNode::HasN::Association:0x007fc05e170590 @type=:has_many, @name=:event_questions, @direction=:in, @target_class_name_from_name="EventQuestion", @target_class_option="::EventQuestion", @callbacks={:before=>nil, :after=>nil}, @origin=nil, @relationship_class=nil, @relationship_type=:questions_of, @dependent=:destroy, @unique=nil, @target_class_name="::EventQuestion", @target_class_name_or_nil="::EventQuestion">, @context="Event#event_questions", @options={:session=>Neo4j::Server::CypherSession url: 'http://localhost:7474/db/data/' version: '2.2.0-M01', :start_object=>#<Event>, :node=>nil, :rel=>nil, :caller=>#<Event>}, @node_var=nil, @rel_var=:rel0, @session=Neo4j::Server::CypherSession url: 'http://localhost:7474/db/data/' version: '2.2.0-M01', @caller=#<Event>, @chain=[], @starting_query=nil, @optional=nil, @params={}> 
2.2.0 :061 > e1.event_questions << q2
 CYPHER 4ms MATCH (start:`Event`), (end:`EventQuestion`) WHERE ID(start) = {start_id} AND ID(end) = {end_id} CREATE start<-[rel0:`questions_of`]-end | {:start_id=>23, :end_id=>26}
 => #<Neo4j::ActiveNode::Query::QueryProxy:0x007fc05e1f08f8 @model=EventQuestion, @association=#<Neo4j::ActiveNode::HasN::Association:0x007fc05e170590 @type=:has_many, @name=:event_questions, @direction=:in, @target_class_name_from_name="EventQuestion", @target_class_option="::EventQuestion", @callbacks={:before=>nil, :after=>nil}, @origin=nil, @relationship_class=nil, @relationship_type=:questions_of, @dependent=:destroy, @unique=nil, @target_class_name="::EventQuestion", @target_class_name_or_nil="::EventQuestion">, @context="Event#event_questions", @options={:session=>Neo4j::Server::CypherSession url: 'http://localhost:7474/db/data/' version: '2.2.0-M01', :start_object=>#<Event>, :node=>nil, :rel=>nil, :caller=>#<Event>}, @node_var=nil, @rel_var=:rel0, @session=Neo4j::Server::CypherSession url: 'http://localhost:7474/db/data/' version: '2.2.0-M01', @caller=#<Event>, @chain=[], @starting_query=nil, @optional=nil, @params={}> 
2.2.0 :062 > e2.event_questions << q3
 CYPHER 3ms MATCH (start:`Event`), (end:`EventQuestion`) WHERE ID(start) = {start_id} AND ID(end) = {end_id} CREATE start<-[rel0:`questions_of`]-end | {:start_id=>24, :end_id=>27}
 => #<Neo4j::ActiveNode::Query::QueryProxy:0x007fc05e300108 @model=EventQuestion, @association=#<Neo4j::ActiveNode::HasN::Association:0x007fc05e170590 @type=:has_many, @name=:event_questions, @direction=:in, @target_class_name_from_name="EventQuestion", @target_class_option="::EventQuestion", @callbacks={:before=>nil, :after=>nil}, @origin=nil, @relationship_class=nil, @relationship_type=:questions_of, @dependent=:destroy, @unique=nil, @target_class_name="::EventQuestion", @target_class_name_or_nil="::EventQuestion">, @context="Event#event_questions", @options={:session=>Neo4j::Server::CypherSession url: 'http://localhost:7474/db/data/' version: '2.2.0-M01', :start_object=>#<Event>, :node=>nil, :rel=>nil, :caller=>#<Event>}, @node_var=nil, @rel_var=:rel0, @session=Neo4j::Server::CypherSession url: 'http://localhost:7474/db/data/' version: '2.2.0-M01', @caller=#<Event>, @chain=[], @starting_query=nil, @optional=nil, @params={}> 
2.2.0 :063 > q1.event_answers << a1
 CYPHER 3ms MATCH (start:`EventQuestion`), (end:`EventAnswer`) WHERE ID(start) = {start_id} AND ID(end) = {end_id} CREATE start<-[rel0:`answers_of`]-end | {:start_id=>25, :end_id=>28}
 => #<Neo4j::ActiveNode::Query::QueryProxy:0x007fc05e350c20 @model=EventAnswer, @association=#<Neo4j::ActiveNode::HasN::Association:0x007fc05bc4f2c0 @type=:has_many, @name=:event_answers, @direction=:in, @target_class_name_from_name="EventAnswer", @target_class_option="::EventAnswer", @callbacks={:before=>nil, :after=>nil}, @origin=nil, @relationship_class=nil, @relationship_type=:answers_of, @dependent=:destroy, @unique=nil, @target_class_name="::EventAnswer", @target_class_name_or_nil="::EventAnswer">, @context="EventQuestion#event_answers", @options={:session=>Neo4j::Server::CypherSession url: 'http://localhost:7474/db/data/' version: '2.2.0-M01', :start_object=>#<EventQuestion>, :node=>nil, :rel=>nil, :caller=>#<EventQuestion>}, @node_var=nil, @rel_var=:rel0, @session=Neo4j::Server::CypherSession url: 'http://localhost:7474/db/data/' version: '2.2.0-M01', @caller=#<EventQuestion>, @chain=[], @starting_query=nil, @optional=nil, @params={}> 
2.2.0 :064 > q2.event_answers << a2
 CYPHER 4ms MATCH (start:`EventQuestion`), (end:`EventAnswer`) WHERE ID(start) = {start_id} AND ID(end) = {end_id} CREATE start<-[rel0:`answers_of`]-end | {:start_id=>26, :end_id=>29}
 => #<Neo4j::ActiveNode::Query::QueryProxy:0x007fc05e4003a0 @model=EventAnswer, @association=#<Neo4j::ActiveNode::HasN::Association:0x007fc05bc4f2c0 @type=:has_many, @name=:event_answers, @direction=:in, @target_class_name_from_name="EventAnswer", @target_class_option="::EventAnswer", @callbacks={:before=>nil, :after=>nil}, @origin=nil, @relationship_class=nil, @relationship_type=:answers_of, @dependent=:destroy, @unique=nil, @target_class_name="::EventAnswer", @target_class_name_or_nil="::EventAnswer">, @context="EventQuestion#event_answers", @options={:session=>Neo4j::Server::CypherSession url: 'http://localhost:7474/db/data/' version: '2.2.0-M01', :start_object=>#<EventQuestion>, :node=>nil, :rel=>nil, :caller=>#<EventQuestion>}, @node_var=nil, @rel_var=:rel0, @session=Neo4j::Server::CypherSession url: 'http://localhost:7474/db/data/' version: '2.2.0-M01', @caller=#<EventQuestion>, @chain=[], @starting_query=nil, @optional=nil, @params={}> 
2.2.0 :065 > q3.event_answers << a3
 CYPHER 4ms MATCH (start:`EventQuestion`), (end:`EventAnswer`) WHERE ID(start) = {start_id} AND ID(end) = {end_id} CREATE start<-[rel0:`answers_of`]-end | {:start_id=>27, :end_id=>30}
 => #<Neo4j::ActiveNode::Query::QueryProxy:0x007fc05e4c1708 @model=EventAnswer, @association=#<Neo4j::ActiveNode::HasN::Association:0x007fc05bc4f2c0 @type=:has_many, @name=:event_answers, @direction=:in, @target_class_name_from_name="EventAnswer", @target_class_option="::EventAnswer", @callbacks={:before=>nil, :after=>nil}, @origin=nil, @relationship_class=nil, @relationship_type=:answers_of, @dependent=:destroy, @unique=nil, @target_class_name="::EventAnswer", @target_class_name_or_nil="::EventAnswer">, @context="EventQuestion#event_answers", @options={:session=>Neo4j::Server::CypherSession url: 'http://localhost:7474/db/data/' version: '2.2.0-M01', :start_object=>#<EventQuestion>, :node=>nil, :rel=>nil, :caller=>#<EventQuestion>}, @node_var=nil, @rel_var=:rel0, @session=Neo4j::Server::CypherSession url: 'http://localhost:7474/db/data/' version: '2.2.0-M01', @caller=#<EventQuestion>, @chain=[], @starting_query=nil, @optional=nil, @params={}> 
2.2.0 :066 > 
2.2.0 :067 >   Event.count
 CYPHER 4ms MATCH (n:`Event`) RETURN count(n) AS count
 => 2 
2.2.0 :068 > EventQuestion.count
 CYPHER 3ms MATCH (n:`EventQuestion`) RETURN count(n) AS count
 => 3 
2.2.0 :069 > EventAnswer.count
 CYPHER 3ms MATCH (n:`EventAnswer`) RETURN count(n) AS count
 => 3 
2.2.0 :070 > 
2.2.0 :071 >   e1.destroy
 Event#event_questions 31ms MATCH (event23:`Event`), (result_event_questions:`EventQuestion`), event23<-[rel0:`questions_of`]-(result_event_questions:`EventQuestion`) WHERE ID(event23) = {ID_event23} RETURN result_event_questions | {:ID_event23=>23}
 EventQuestion#event_answers 29ms MATCH (eventquestion26:`EventQuestion`), (result_event_answers:`EventAnswer`), eventquestion26<-[rel0:`answers_of`]-(result_event_answers:`EventAnswer`) WHERE ID(eventquestion26) = {ID_eventquestion26} RETURN result_event_answers | {:ID_eventquestion26=>26}
 EventQuestion#event_answers 31ms MATCH (eventquestion25:`EventQuestion`), (result_event_answers:`EventAnswer`), eventquestion25<-[rel0:`answers_of`]-(result_event_answers:`EventAnswer`) WHERE ID(eventquestion25) = {ID_eventquestion25} RETURN result_event_answers | {:ID_eventquestion25=>25}
 => true 
2.2.0 :072 > EventQuestion.count
 CYPHER 4ms MATCH (n:`EventQuestion`) RETURN count(n) AS count
 => 1 
2.2.0 :073 > EventAnswer.count
 CYPHER 3ms MATCH (n:`EventAnswer`) RETURN count(n) AS count
 => 1 
2.2.0 :074 > 
2.2.0 :075 >   e2.destroy
 Event#event_questions 31ms MATCH (event24:`Event`), (result_event_questions:`EventQuestion`), event24<-[rel0:`questions_of`]-(result_event_questions:`EventQuestion`) WHERE ID(event24) = {ID_event24} RETURN result_event_questions | {:ID_event24=>24}
 EventQuestion#event_answers 29ms MATCH (eventquestion27:`EventQuestion`), (result_event_answers:`EventAnswer`), eventquestion27<-[rel0:`answers_of`]-(result_event_answers:`EventAnswer`) WHERE ID(eventquestion27) = {ID_eventquestion27} RETURN result_event_answers | {:ID_eventquestion27=>27}
 => true 
2.2.0 :076 > EventQuestion.count
 CYPHER 3ms MATCH (n:`EventQuestion`) RETURN count(n) AS count
 => 0 
2.2.0 :077 > EventAnswer.count
 CYPHER 3ms MATCH (n:`EventAnswer`) RETURN count(n) AS count
 => 0 
2.2.0 :078 > 
subvertallchris
  • 5,282
  • 2
  • 25
  • 43
  • i've isolated the issue more around my `event` to `event_question` setup.. if i hit my destroy action on my `event_question` controller, the `event_answers` do destroy. still not sure where to look since the remaining destroy code is doing things like changing a users event count. `user.events_attended -= 1` etc.. `user.save` – Clam Jan 13 '15 at 19:17
  • so for whatever reason, altering those property counts does interfer with it. what i did was move it to after the destroy actions. If i had it before, it broke the chain destroy. – Clam Jan 16 '15 at 21:17