rails activerecord belongs_to problem - can't insert - ruby-on-rails

Seems simple, but having an issue:
model A
belong_to :B
model B
has_many :A
database tables:
table A:
id,...,b_id
table B:
id,...
When trying to create a new A, I set (an existing) B by doing:
a.b = B
I get an error saying "b can't be blank"

Instead of doing a.b = B, do a.b_id = B.id.

Think about how your collection and parent-child relationships work. You can -as suggested- add the ID of the relevant B to your A, but you may alternatively want to say B.a[] = a which would add "a" to your the "a" collection of your object "B". That way the relationship is set up in a more intuitive way, oriented towards the parent object rather than the child.

You should also be able to do newA = B.as.build ('as' being the plural of a).
Of course your examples of 'A, a, B and b` are very confusing! In the future use 'customer' & 'order' or 'blog' & 'post' or anything but cryptic letters with no meaning.

Related

Transitive graph relationship mapping back to the same label

How do I create a transitive relationship which maps back to the same initial label.
I am trying to map data from tables that go something like this :-
A -> B -> C -> A
B has the index column from A, and C has the index column from B and A (multiple). It is a kind of transitive relationship, wherein I need to map a specific row in A back to different rows in A. How do I go about doing this?
This is to be done on the labels for the whole data set, and not to be filtered for any given id. The labels are already existing in the db.
If you already have relations from A->B and B->C, then it can be simply achieved as follows, assuming the relationship type to be X:
MATCH (a:A)-[:X]->(:B)-[:X]->(c:C)
MERGE (c)-[:X]->(a)
This will create a relationship between every C and A, when they are linked via B

Replace a Relationship-Node->Relationship construct with one Realtionship containing the label of the replaced node

I have a graph where if have the following constructs:
(a)-[b:Input]->(c:Data)-[e:Output]->(f)
i want to replace b,c,e with a relationship with the label from c:
(a)-[n:Data]->(f)
The label should be generated automatically. I have multiple labels for c like: Data, AMC, Door, New_HS etc..
So the label of the new created relationship should be created like this:
[n:title = c.Label]
We cannot create a relationship based on a property. You need to create a new relationship and change the type (or relationship name) to your data label name. I used an apoc function to change (or update) that. What I did is
Find all nodes and relationship that are attached to Data
Create the needed relationship but use a dummy relationship type: REL
Use apoc function apoc.refactor.setType to change the relationship type from REL to c.label
Don't forget to remove the dummy relationship REL
Match (a)-[:Input]->(c:Data)-[:Output]->(f)
CREATE (a)-[r:REL]->(f)
WITH a, r, c, f
CALL apoc.refactor.setType(r, c.label)
YIELD input, output
WITH a, c, f
MATCH (a)-[rel:REL]->(f)
DELETE rel
RETURN a, f
BEFORE:
AFTER:

Only show nodes that have a specific properties in relationship

I'm new to neo4j and im struggling with the task to build a simple filter.
I played around and found the in operator but it only list me every "Person" where atleast one match is found. I want to only list "Person" that have all the properties included.
MATCH (p:Person)-[l:LIKES]->(f:Food) WHERE f.name in ["Spaghetti","Cheese","Chicken","Eggs"]
RETURN p
Result: Show only "Person" that like "Spaghetti","Cheese","Chicken","Eggs", ...
We have a knowledge base article on performing match intersection that should address this.
Applied to your case, here's one of the approaches you can use:
WITH ["Spaghetti","Cheese","Chicken","Eggs"] as foods
MATCH (p:Person)-[:LIKES]->(f:Food)
WHERE f.name in foods
WITH p, foods, count(f) as foodsLiked
WHERE foodsLiked = size(foods)
RETURN p

Mapping amount of properties

i want to map 2 different Ontologies A and B. But the classes i want to map have a different amount of object properties.Lets say A equals b. A is father and B is mother. class A:(gender, age, eyecolour, brother) class B:(age, gender, haircolour, sport)
the Union of A and B say C got:(gender, age, eyecolour, haircolour, sport) right? Is there any create statement in owL? or do i need to make the equvivalent to statement for the object properties. Is there any statement lets say if A got 2 brothers, create the object property x in B.
OWL classes aren't classes in the object-oriented programming sense, properties don't "belong" to classes in the sense that methods belong to classes (in many OO programming languages). When you say that the domain of a property P is the class C, it means that whenever you have an assertion
P(x,y)
you can infer that
x is a C
If you assert that the
P domain A
Q domain A
R domain B
S domain B
T domain B
and then assert that
C equivalentClass (A union B)
then you'll be able to infer that
P domain C
Q domain C
R domain C
S domain C
T domain C
Since, e.g.,
P(x,y)
implies
x is an A
which in turn implies that
x is a (A union B)
which implies that
x is a C
So C is a domain of P. I think that's what you're meaning when you say that "the class C has property P."

neo4j distinct two columns

How to return two different columns with cypher in Neo4j? The query which I've got is that:
MATCH (a:Person)-[r:WorksFOR]->(b:Boss), (c:Boss)<-[r2:WorksFOR]-(d:Person)
WHERE b.sex = c.sex
RETURN a, d;
And it returns:
a d
John Will
Will John
I want to get rid of one of the column.
OP needs to reword the question to clarify OP wants to get rid of one of the rows.
Here's a query that does that:
MATCH (a:Person)-[r:WorksFOR]->(b:Boss), (c:Boss)<-[r2:WorksFOR]-(d:Person)
WHERE b.name < c.name AND
b.sex = c.sex AND
b <> c
RETURN a, d;
The problem with your query is that b and c can match any Boss. To force them to match in one order, I've added b.name < c.name. The order doesn't matter, this just forces it to match one way, but not the other. I've added b <> c because you have to handle the case where they work for the same boss, which I don't think you want.
Once you add the ordering, the boss matching (b and c) can only happen one way, not the other way, so your second row of results gets eliminated.

Resources