-
-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Back-referencing relationship: am I doing it a wrong way? #472
Comments
Red's relationships, by default, expects a relationship $ to @, so if it's a @, and it will searches the id on the $ one. If on that relationship it's $ to $ (to-one relationship), it will try to find the id on it self (on both sides). To change that, you can use the experimental feature "has-one", that adds the parameter use Red <has-one>;
model m1 is nullable {
has UInt $.id is serial;
has Str $.name is column;
has $.m2 is relationship(*.m1-id, :model<m2>, :has-one);
}
model m2 is nullable {
has UInt $.m1-id is referencing(*.id, :model<m1>);
has Str $.descr is column;
}
red-defaults "SQLite"; my $*RED-DEBUG = True;
say schema(m1, m2).create;
say (m1.^create: :name<test>); that prints:
|
I'd like to have more people testing it to let it evolve and make it not experimental anymore. |
Thanks! I thought that a scalar relationship is not experimental anymore. In the form you provided it does create the schema. But then troubles begin. m1.^create: :name<test>, :m2{ :descr<test-descr> }; It results in
I try it other way around: my $m1 = m1.^create: :name<test>;
$m1.m2.create: :descr<test-descr>;
say ($m1 = m1.^find: :name<test>);
say m2.^find: :descr<test-descr>; And it goes without an error, but:
So, we end up with no Eventually, the only one which works is: my $m1 = m1.^create: :name<test>;
m2.^create: :m1-id($m1.id), :descr<test-descr>; Not the most user-friendly one, though. For the sake of DWIM, it'd be great if the other two work as well. :) |
Yes... that's a bug indeed. I'll try to fix that as soon as possible. |
I think I've "kinda fixed it"... but there is a problem...
I don't know how to populate |
@vrurg now it seems to be working! It will work for a single id (I have to find a way to make it work for multiple ids)
Could you test it out, please? |
Ok, so far One way or another, it works and I have ways to proceed. Thank you! Just one question out of curiosity: do we really need |
Perhaps a useful observation. Here is debug print I get with my almost real life models:
It feels to me that one Otherwise, when trying to introspect the data I put into a DB here is what I get when refer to a
Haven't golfed it down to something comprehensible and it's actually time to call it a day. So, leaving it here just as a side note. Will try to diagnose tomorrow. |
Yes, The reason we need |
If rather than |
ResultSeq already has a way of doing that, that's how That's why I've being thinking on return a ResultSeq when there is no object set. |
With regard to multi trait_mod:<is> (Attribute:D $a is raw, :$foo!) {
$a.auto_viv_container = class {
method create(*%c) {
say "CREATING WITH ", %c;
}
};
}
class Foo {
has $.a is foo;
}
my $foo = Foo.new;
$foo.a.create(:1a, :2b); Apparently, this will require more work to be done correctly. For example, with Similarly, when it comes to |
Ok, the above example was a quick hack, a proof of concept. Here is what I came up with to support assignment of use nqp;
multi trait_mod:<is> (Attribute:D $a is raw, :$foo!) {
my role ModHelper {
method create(*%c) {
say "CREATING WITH ", %c;
}
};
if nqp::defined($a.container_descriptor.default) {
$a.container_descriptor.default does ModHelper;
} else {
my $def := $a.container_descriptor.default but ModHelper;
nqp::bindattr(
nqp::decont($a.container_descriptor), ContainerDescriptor, '$!default', $def);
nqp::bindattr($a.auto_viv_container, Scalar, '$!value', $def);
}
}
class Foo {
has Int $.a is rw is default(666) is foo;
}
my $foo = Foo.new;
note "attr on instance: ", $foo.a.WHICH;
$foo.a.create(:1a, :2b);
$foo.a = 42;
say "-> ", $foo.a;
$foo.a = Nil;
note $foo.a.WHICH;
$foo.a.create(:3c, :4d); The interesting part of it is that it is actually possible set attribute type to the model it is refers to. I.e.: model Foo {
has $.attr is column(..., :model<MyModel>);
}
Foo.attr.WHICH # MyModel |
Closing this one and creating #475 to continue the |
I'm trying this simple structure:
It ends up with:
Basically, the idea is that
m2
is a kind of profile attached to a user accountm1
. It'sid
will always be the same as account'sid
. And there will always either be a profile record, or not. So,$m1.m2
could be either defined or undefined.Ok, if
Red
expected a record inm2
to always exists for correspondingm1
record then I shall create one. So, I try:But it results in the same error as above.
The text was updated successfully, but these errors were encountered: