ruby-on-railsrubyactiverecordneo4jneo4j.rb

How can I get all ActiveRel between two ActiveNode in Neo4j ruby?


Suppose we have

representing a simplized Bitcoin-like transaction, where a User sends coins to other Users. A Transaction has a property amount which shows how much coin you're sending to the to_node from from_node.

Then now I want to get all the transactions (either uni- or bi- directionally) between Alice and Bob. How can I do this?

# user.rb
has_many :out, :receivers, rel_class: :Transaction
has_many :in, :senders, rel_class: :Transaction


# Console
alice = User.find_by(name: "Alice")
bob = User.find_by(name: "Bob")

# I want to do something like this:
Transaction.between(from: alice, to: bob)

# or this:
alice.receivers.rel_where(to_node: bob)

I was surprised that the latter isn't acceptable. It includes bob directly into CYPHER.

Using Neo4jrb v8.0.0


Solution

  • I struggled and came to know I can do something like this:

    alice.receivers.match_to(bob).pluck(:rel1)
    

    With this we can get all the transactions sent from alice to bob, but I think it's not a good idea using the magical :rel1 here (which is available because it is automatically written in the CYPHER, and match_to returns a QueryProxy object: match_to)

    But it is always not much encouraged to get just the Rels.
    Relatively, we could

    alice.receivers.match_to(bob).rel_where(amount: 1.0)   # Txs which amount are 1.0btc
    

    and

    alice.receivers.match_to(bob).each_rel.sum {|rel| rel.amount }   # All the sent money!
    

    怀
    Note that you can't do this (somehow):

    alice.receivers.match_to(bob).rel_where("rel1.amount < 10.0")
    

    but can go-around with this:

    query = alice.receivers.match_to(bob)          # create just the query
    query.where("#{query.rel_var}.amount < 10.0")  # you can get `:rel1` by `rel_var`