0

I know that the gem doesn't have a built in way to handle dependency destroys yet like active rececord dependant: destroy

Is there better ways to deal with chain destroying?

For example, right now I am trying to deal with destroying with my Q+A

Each question has many answers and each answer has one question

Destroying the question can be done like so

event_question = EventQuestion.find(params[:id])

event_question.destroy

but if I need to deal with the answers, and I do it through this association, I have to loop through and destroy each one. An added weakness is needing to check if the dependent nodes/relationships even exist.

Is it better to write out a longer query to deal with finding both the questions and answers and destroying them in one swoop? (or... can you?) I know you can't destroy the queryproxy like so (e.g. event_question.answers.destroy)

UPDATE

I've tried to implement these two queries with delete but delete doesn't execute. No error message right now. Prying into the method, the matches look right.

event.users(:u,:rel).query.match("()-[r3]-u").delete(:r3).exec
event.event_questions(:q).event_answers(:a).query.match("event-[r0]-(), q-[r1]-(), a-[r2]-()").delete(:q, :a, :event).exec

UPDATE 2

This is the cypher query for the first event.users.

MATCH (event13:`Event`), (u:`User`), event13-[rel:`invited`]-(u:`User`), ()-[r3]-u WHERE ID(event13) = {ID_event13} DELETE r3"

It looks right? But delete doesn't seem to execute. Attaching as or query_as doesn't allow the query to go through on the second one. It gives me undefined method as

LAST UPDATE

Last update before moving to a different question.

Oddly, I can get the first query to delete the relationship via this

event.users(:u,:r3).query.match("()-[r]-u").delete(:r3).exec

but this next query won't delete the question and answers.

event.event_questions(:q).event_answers(:a).query.match("q-[r1]-(), a-[r2]-()").delete(:q, :a).exec

I'm not entirely sure why the match is needed but without it, it doesn't execute either. When I wrote my destroy functions on my Questions/Answers controller, I didn't actually have to delete the relationship. But maybe I did something funky.

I actually did this

answers = event_question.event_answers

and then looped it and destroyed each answer, which seemed to destroy both answer and the relationship with the question. The Q+A are set up through associations and not ActiveRel.. not sure if that makes a difference.

Clam
  • 935
  • 1
  • 12
  • 24

2 Answers2

2

The gem implements callbacks with ActiveModel. So you can do:

class EventQuestion
  before_destroy :destroy_answers

  def destroy_answers
    answers.each(&:destroy)
  end
end

Obviously that's not the most efficient as it does a destroy for each answer which is it's own query. It does have the advantage that all of the before/after destroy callbacks on the answers will be called, though.

If you wanted to just delete them with cypher you should be able to do answers(:a, :r).delete(:a, :r).exec

Brian Underwood
  • 10,746
  • 1
  • 22
  • 34
  • yeah that could be a lot of queries if i am dealing with lots of linked nodes. would that example above have issues if answers is blank? i've never seen `.delete` or `.exec` mentioned in the docs? – Clam Dec 22 '14 at 19:33
  • Do you mean if the answers association is empty? It shouldn't as it's just iterating over an empty enumeration – Brian Underwood Dec 22 '14 at 21:12
  • Also, `delete` and `exec` are part of the `Query` API which is part of neo4j-core, which is probably why you missed it. We're working on a new website now and we need to do a better job of organizing our docs, but for now it's here: https://github.com/neo4jrb/neo4j-core/wiki/Queries – Brian Underwood Dec 22 '14 at 21:13
  • ah right, always forget about the core. I'm about to try this `event.event_questions(:q).event_answers(:a).delete(:q, :a).exec` which I think would work based on the answer above. – Clam Dec 22 '14 at 23:06
  • i wasn't able to do it all in one query as i also have things like users which are attached to the event but aren't part of this chain – Clam Dec 22 '14 at 23:27
  • This `event.users(:u,:rel).delete(:rel).exec` gives me a nomethod error for delete on the queryproxy. The doc pages aren't found right now (which I'm guessing you're migrating) – Clam Dec 23 '14 at 00:04
  • Ah, yeah, you can do delete in QueryProxy too. If you want to delete the node and all it's relationships even if they're not in the chain this might work: `event.event_questions(:q).event_answers(:a).query.match("q-[r1]-(), a-[r2]-()").delete(:q, :a, :r1, :r2).exec` – Brian Underwood Dec 23 '14 at 08:06
  • I added my latest queries to an edited version of the question. No errors or thrown but delete doesn't seem to execute – Clam Dec 23 '14 at 23:12
  • In your ruby code `event` is a ruby variable, but it's not being declared in the cypher as a variable, so you wouldn't be able to `MATCH` and `DELETE` on it. I think you can start that line with `event.as(:event).event_questions(:q)....` to do that. Also see what you get when you call `to_cypher` instead of `exec` and output the result. It should show you the cypher query that would be generated – Brian Underwood Dec 24 '14 at 07:26
  • The first query goes through with what seems to be right query, just doesn't execute the delete. See further details in second update. – Clam Dec 24 '14 at 09:42
0

Chris and company is working on a PR for the dependent destroy ability. It seems to work on master branch of the gem currently. It seems to do the job a -ok!

https://github.com/neo4jrb/neo4j/pull/653

Clam
  • 935
  • 1
  • 12
  • 24