Coder Social home page Coder Social logo

Create a better relationship about red HOT 12 CLOSED

FCO avatar FCO commented on August 28, 2024
Create a better relationship

from red.

Comments (12)

FCO avatar FCO commented on August 28, 2024
has Track %.cd-tracks{CD} is relationship({ .artist-id },{ .cd-id });
$artist.cds-tracks.keys; # list the artist’s cds
$artist.cds-tracks.values; # list the artists’s tracks
$artist.cds-tracks{ :title("cd title") }; # list the tracks of the cd with title “cd title” of the artist

from red.

moritz avatar moritz commented on August 28, 2024
 has Track %.cd-tracks{CD} is relationship({ .artist-id },{ .cd-id });

How does that work? What kind of object is passed to the callbacks? I don't even see an object that has a cd-id attribute or method.

from red.

FCO avatar FCO commented on August 28, 2024

The idea is: for the first Block it'll pass a CD type object and for the second one a Track type object. both gotten from the type of the parameter.

as it does with the positional one.

@moritz And I'm sorry... its not all the code... its based on this example: https://github.com/FCO/Red/wiki/CD-sample
cd-id is from the Track class

from red.

FCO avatar FCO commented on August 28, 2024

lib/Track.pm6

use Red;

model CD { ... }
model Artist { ... }

model Track {
   has Uint  $.id             is column{ :id, :!nullable };
   has Uint  $.cd-id          is referencing{ CD.id };
   has Str   $.title          is column;
   has Track %.cds-tracks{CD} is relationship({ .artist-id },{ .cd-id });

   ::?CLASS.^add-unique-constraint: { .cd-id, .title };
}

lib/CD.pm6

use Red;
use Track;

model Artist { ... }

model CD {
   has UInt   $.id          is column{ :id, :!nullable };
   has UInt   $!artist-id   is referencing{ Artist.id };
   has Str    $.title       is column;
   has UInt   $.year        is column;
   has Artist $.artist      is relationship{ .artist-id };
   has Track  @.tracks      is relationship{ .cd-id };

   ::?CLASS.^add-unique-constraint: { .artist-id, .title };
}

lib/Artist.pm6

use Red;
use CD;

model Artist {
   has UInt $.id    is column{ :id, :!nullable };
   has Str  $.name  is column{ :unique, :!nullable };
   has CD   @.cds   is relationship{ .artist-id };
}

from red.

MattOates avatar MattOates commented on August 28, 2024

So one thing missing is perhaps annotating the primary key (possibly composite) rather than just unique constraint, I assume here the :id on a column is that its a primary key with an auto index for that one column? perhaps :pk ? with :id being a special single column case of that. In SQLAlchemy at least the auto increment is implied by the type of a primary key, if its a single int column its assumed its a serial etc. I actually think thats a mistake because its not obvious when you're new, and sometimes you might not actually want it as behaviour.

from red.

FCO avatar FCO commented on August 28, 2024

Yes, the :id means primary key and you can :id more than one column to make a composed pk (on the arguments order). But if you prefer you could also do ::?CLASS.^add-primary-key: { .bla, .ble } (NYI).
there are more planned ways to "create a primary key", like #18 and #19.

from red.

perlpilot avatar perlpilot commented on August 28, 2024

Was just playing around with the syntax a little bit. I hope it makes sense since I'm a kinda tired right now:

model CD {
   column UInt   $.id          is ID{ :!nullable, :auto-increment };
   column UInt   $!artist-id   is referencing{ Artist.id };
   column Str    $.title;
   column UInt   $.year;

   column Artist $.artist      is has-one{ Artist.artist-id };
   column Track  @.tracks      is has-many{ Track.cd-id };

   ::?CLASS.^add-unique-constraint: { .artist-id, .title };
}

model Artist {
   column UInt $.id    is ID{ :!nullable, :auto-increment };
   column Str  $.name  is constraint{ :unique, :!nullable };
   column CD   @.cds   is has-many{ .artist-id };
}

model Track {
   column Uint  $.id             is ID{ :!nullable, :auto-increment };
   column Uint  $.cd-id          is has-one{ CD.id };
   column Str   $.title;
   column Track %.cds-tracks{CD} is relationship({ .artist-id },{ .cd-id }); 

   ::?CLASS.^add-unique-constraint: { .cd-id, .title };
}

from red.

FCO avatar FCO commented on August 28, 2024

Hi @perlpilot! Thanks for your help!

My idea of not using explicitly the type, as on is has-many{ Track.cd-id }, because I plan to use an alias for that.
I was thinking about has-many and has-one... the original idea was that it can be inferred by the tipe of the attribute, if its Positional or not.
I think I like the column keyword.
And why uppercased ID?

Another thing: on actual implementation relationship aren't column. Do you think it should be?

from red.

perlpilot avatar perlpilot commented on August 28, 2024

My idea of not using explicitly the type, as on is has-many{ Track.cd-id }, because I plan to use an alias for that.

I was thinking that it could be either or. Left off for terseness, but allowed for documentation purposes.

I was thinking about has-many and has-one... the original idea was that it can be inferred by the tipe of the attribute, if its Positional or not.

I dunno. Why I used explicit naming of the relationships was for documentation purposes. It makes it a little easier to see what's going on.

And why uppercased ID?

I told you I was tired :-) I should have expounded a little on what was going on in my head. Uppercase ID because it seems "special" in that it could imply :!nullable and :auto-increment (or, of course, those could also be spelled out).

Another thing: on actual implementation relationship aren't column. Do you think it should be?

I dunno. Even though they aren't actual columns, they act as such as far as the ORM is concerned. Maybe another declarator?

model CD {
    ...
    relationship Artist $.artist   is has-one{ .artist-id }
}

It jibes with my leaning towards self-documention.

I like where you're going with this, but it feels like one of those things where if you get all the details right, it'll be awesome and if you miss a few things, it'll just be meh. For instance, the way the %.cds-tracks{CD} relationship is expressed doesn't seem quite right to me (that might just be in my head though :-). It feels like there should be something better.

Anyway, keep up the good work! Maybe get some input from people who have built ORMs (like Matt Trout). More input and more ideas can only make it better. :-)

from red.

FCO avatar FCO commented on August 28, 2024

I dunno. Why I used explicit naming of the relationships was for documentation purposes. It makes it a little easier to see what's going on.

What do you think should happen if some one do: has @.cds is has-one{ .cd-id }?

I told you I was tired :-) I should have expounded a little on what was going on in my head. Uppercase ID because it seems "special" in that it could imply :!nullable and :auto-increment (or, of course, those could also be spelled out).

Had you had time to take a look at #18 and #19?

from red.

FCO avatar FCO commented on August 28, 2024

@perlpilot, @moritz @MattOates : what do you guys think about this?

model Artist { ... }

model CD {
   has UInt      $.id        is id;;
   has           $!artist-id is referencing{ Artist.id };
   has Artist    $.author    is relationship{ .artist-id };
}

model Track {
   has UInt   $.id     is id;
   has        $!cd-id  is referencing{ CD.id };
   has CD     $.cd     is relationship{ .cd-id };
   has Artist $.artist = $!cd.artist;
}

model Artist {
   has UInt  $.id     is id;
   has CD    @.cds    is relationship{ .artist-id };
   has Track @.tracks = @!cds.flatmap: *.tracks;
}

from red.

FCO avatar FCO commented on August 28, 2024

This last example is what's "working" now!
what do you guys think?

from red.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.