Code Monkey home page Code Monkey logo

Comments (65)

nappa85 avatar nappa85 commented on May 13, 2024 2

I've put together a minimal impl, have a look https://github.com/nappa85/sea-orm-macro/
Inside tests there is a working example.
Sure there is space for improvement, but it can be a starting point

from sea-orm.

tqwewe avatar tqwewe commented on May 13, 2024 2

@tyt2y3 I spent most of my day yesterday and today creating a PR for this too. It's at a working stage, just need the columntrait to be generated too.

I'll create the PR in a few hours!

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024 2

So based on @nappa85 work, I have had something in mind:

Basic usage

use sea_orm::EntityModel;

#[derive(EntityModel)]
struct Model {
    id: u64,
    name: String,
}

this will autogenerate the Column enum (omitted here).

Primary key

To autogenerate the PrimaryKey enum too, simply add the attribute like this:

use sea_orm::EntityModel;

#[derive(EntityModel)]
struct Model {
    #[sea_orm(primary_key)]
    id: u64,
    name: String,
}

this will autogenerate the PrimaryKey enum, with implied auto_increment = true.

If we instead want auto_increment = false, we can specify:

#[sea_orm(primary_key, auto_increment = false)]

For composite primary key, we can annotate a column multiple times:

struct Model {
    #[sea_orm(primary_key)]
    id1: i32,
    #[sea_orm(primary_key)]
    id2: i32,
}

And auto_increment will be false automatically.

Custom types

If your struct uses a non-basic type, you'll have to specify the SQL type for that column:

use sea_orm::EntityModel;

#[derive(EntityModel)]
struct Model {
    #[sea_orm(primary_key)]
    id: u64,
    #[sea_orm(column_type = "String(Some(255))", default_value = "new user")]
    name: MyName,
    #[sea_orm(default_expr = "gen_random_uuid()", indexed)]
    uuid: Uuid,
    #[sea_orm(column_type = "Char(Some(1))", unique, nullable)]
    admin: Option<MyBool>,
}

These will corresponds to the following column definitions:

ColumnType::String(Some(2555)).def().default_value("new user")
ColumnType::Uuid().def().default_expr("gen_random_uuid()").indexed()
ColumnType::Char(Some(1)).def().unique().nullable()

That said, 3 more methods will be added:

fn default_value(self, v: V) where V: IntoValue { ... }
fn default_expr(self, expr: &str) { ... }
fn nullable(self) { ... }

I think this will also addresses #101
Let's discuss a bit before putting this into implementation.

from sea-orm.

billy1624 avatar billy1624 commented on May 13, 2024 2

I am thinking, whether DeriveEntityModel should automatically derive DeriveModel and DeriveActiveModel, to make it less verbose.

I've made some tests about it, maybe I'm wrong, but it seems that a derive macro can't edit the original struct, to do so you need a proc-macro.

I've tried with this code, inside DeriveEntityModel macro:

    attrs.push(Attribute {
        pound_token: Pound(Span::call_site()),
        style: AttrStyle::Outer,
        bracket_token: Bracket(Span::call_site()),
        path: Path {
            leading_colon: None,
            segments: {
                let mut temp = Punctuated::new();
                temp.push(PathSegment {
                    ident: Ident::new("derive", Span::call_site()),
                    arguments: PathArguments::None,
                });
                temp
            },
        },
        tokens: quote! { DeriveModel, DeriveActiveModel },
    });

This is crazy loll

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024 1

Yes, I understand your point of view, and it was exactly the reply I thought for the question "why didn't they already made this?".
But, as @acidic9 pointed, there can be default impl via derive macro and custom impl in plain Rust without any problems.
As far as I can see, code completion works with macro-produced code without problems.
Macros aren't made to replace code, but to easy the life of who writes it.

For example, serde has a derive macro for Serialize and Deserialize, but anyone can manually derive the traits for non-standard situations, and there are lots of docs about it.

I would prefer a serde-like approach, where the default is easily reached with a macro, and non-default-fitting situations can be covered in plain Rust.

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024 1

@acidic9 the format you propose already looks good. Perhaps we just need to think about the relations.

from sea-orm.

tqwewe avatar tqwewe commented on May 13, 2024 1

I've created a PR for this #122

If @nappa85 's version is preferred thats fine with me, just thought I'd share the work as a PR in case it can be used or to share any thoughts.

Let me know what you guys think

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024 1

The problem here is the Entity requires an associated Relation type:

impl EntityTrait for Entity {
    type Model = Model;

    type Column = Column;

    type PrimaryKey = PrimaryKey;

    type Relation = Relation;
}

May be, it's possible for sea_orm to define a NoRelation enum so Entities with no relation can use that

#[sea_orm(table_name = "posts", no_relation)]

As for ActiveModelBehavior, yes it can already be impl automatically by the DeriveActiveModelBehavior macro.

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024 1

I'm still thinking deeply about this.

I am sorry @acidic9 but it seems to be a bit off topic for this thread, can you move that post to a new thread and we'll continue discussion there?

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024 1

Thank you everyone for everything!
I am now working on it. Hopefully will have something out soon.

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024 1

I am thinking, whether DeriveEntityModel should automatically derive DeriveModel and DeriveActiveModel, to make it less verbose.

@billy1624 can you help a bit on this?

from sea-orm.

tqwewe avatar tqwewe commented on May 13, 2024 1

Ah yea you did the same as I explained haha, just call the function directly.

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024 1

This is crazy loll

Yeah, it was a really raw approach

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024 1

Our current DeriveRelation is quite 'copy & paste' now.

I am thinking if instead of

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
    #[sea_orm(
        belongs_to = "super::bakery::Entity",
        from = "Column::BakeryId",
        to = "super::bakery::Column::Id",
        on_update = "Cascade",
        on_delete = "Cascade"
    )]
    Bakery,
}

we do

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
    #[sea_orm(
        belongs_to = "bakery",
        from = "bakery_id",
        to = "bakery.id",
        on_update = "cascade",
        on_delete = "cascade"
    )]
    Bakery,
}

But is this 'too much'?

I think it's becoming too much magic, what if the other entity isn't on the the parent module but it's on another crate?
The first version is better, more explicit

from sea-orm.

tqwewe avatar tqwewe commented on May 13, 2024

I haven't thought of this before, but I think I can agree with you somewhat.

For example, Entity, Model, Column, PrimaryKey, PrimaryKeyTrait & ColumnTrait could be combined into a single struct definition with derives or a single SeaORM derive.
From:

#[derive(Copy, Clone, Default, Debug, DeriveEntity)]
pub struct Entity;

impl EntityName for Entity {
    fn schema_name(&self) -> Option<&str> {
        Some("public")
    }

    fn table_name(&self) -> &str {
        "users"
    }
}

#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]
pub struct Model {
    pub id: Uuid,
    pub created_at: DateTimeWithTimeZone,
    pub updated_at: DateTimeWithTimeZone,
    pub username: String,
    pub password: String,
    pub email: Option<String>,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
pub enum Column {
    Id,
    CreatedAt,
    UpdatedAt,
    Username,
    Password,
    Email,
}


#[derive(Copy, std::clone::Clone, std::fmt::Debug, EnumIter, DerivePrimaryKey)]
pub enum PrimaryKey {
    Id,
}

impl PrimaryKeyTrait for PrimaryKey {
    fn auto_increment() -> bool {
        false
    }
}

#[derive(Copy, Clone, Debug, EnumIter)]
pub enum Relation {}

impl ColumnTrait for Column {
    type EntityName = Entity;
    fn def(&self) -> ColumnDef {
        match self {
            Self::Id => ColumnType::Uuid.def(),
            Self::CreatedAt => ColumnType::Timestamp.def(),
            Self::UpdatedAt => ColumnType::Timestamp.def(),
            Self::Username => ColumnType::String(None).def(),
            Self::Password => ColumnType::String(None).def(),
            Self::Email => ColumnType::String(None).def().null(),
        }
    }
}

Into:

#[derive(Clone, Debug, PartialEq, SeaORM)]
#[schema_name = "public"]
#[table_name = "coupons"]
pub struct Model {
    #[primary_key]
    #[auto_increment = false]
    pub id: Uuid,
    pub created_at: DateTimeWithTimeZone,
    pub updated_at: DateTimeWithTimeZone,
    pub username: String,
    pub password: String,
    pub email: Option<String>,
}

I think this wouldn't be too hard as a lot of information could be inferred from the struct.
For example:

  • If a field is an Option<T>, then .null() would be added in the ColumnTrait
  • The Column enum could be generated from the model's fields

Obviously with this comes a lack of customizability. But this could be solved by allowing manual implementations where needed perhaps?

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

Thank you for your interest. I will first talk about the original ideas and choices, and may add more thoughts on later post.

The first thing is, I do not want to invent any DSL or a custom syntax or semantics. It will definitely be much less verbose, but it will be hard to understand and reason about, and people don't want to learn a new micro-language. Sooner or later, someone will have a need to customise the behaviour and hack the thing, and it will be much easier to do so in the plain Rust language.

(Just a small use case, how can I dynamically remap the table name based on environment variables?)

If there are tricks to reduce the verbosity of the Entity file without countering the above, I'll definitely adopt.

A lesser motivation would be code completion. List out the essential symbols and traits will be helpful.

But after all it is about how much information we want to present on plain sight. Too much it is hard to digest, too little it will be hard to see-through.

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

I also think that having to use both CamelCase and snake_case when referring to attributes is slightly awkward.

Is it better or worse if we break the Rust convention and use snake_case enums?

from sea-orm.

tqwewe avatar tqwewe commented on May 13, 2024

I don't think so honestly, I think keeping the enum as CamelCase... and just renaming it through the derive macro. And the derive macro would just generate an implementation of std::string::ToString

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

Serde is a brilliant library and there is definitely a lot to learn and borrow from.

Yes I would prefer to have a more compact form, as long as it is compatible with the longer form.

And that the derive macro should not do too much magic other than providing syntax sugars.

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

Also, it'd be better if we settle on a 'base format' first, and versions afterwards to be backward compatible.
That way, we can incrementally release enhancements towards the 'short format', while the codegen can maintain the capability to generate both formats.

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

I've put together a minimal impl, have a look https://github.com/nappa85/sea-orm-macro/
Inside tests there is a working example.
Sure there is space for improvement, but it can be a starting point

Wow thank you for the quick update. Looks great so far. I was just thinking how to name it (lol) perhaps, AutoEntity, EntityDef, or simply Entity?

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024

Wow thank you for the quick update. Looks great so far. I was just thinking how to name it (lol) perhaps, AutoEntity, EntityDef, or simply Entity?

I've named it AutoColumn because it's main purpose is to generate Column from Model, but it generates optionally also Entity and PrimaryKey, so maybe a more generic AutoDef?

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

Yeah AutoDef sounds good too.

from sea-orm.

tqwewe avatar tqwewe commented on May 13, 2024

I feel like AutoDef is a little ambiguous. For example, serde just has Serialize and Deserialize. I like the sound of Schema or Entity or Table

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

Well, Entity is the most almighty I guess.

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

@nappa85 we are releasing 0.2.0 soon.
Since you were working on this, do you think you will be able to contribute a bit in the coming month?
Such that we may incorporate and release in 0.3.0

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024

Yes, if you let me know what you want me to edit, I'll do it ASAP

Here we discussed only the derive macro name

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

@tyt2y3 I spent most of my day yesterday and today creating a PR for this too. It's at a working stage, just need the columntrait to be generated too.

I'll create the PR in a few hours!

Thank you. After 0.2.0 we will make our focus on this matter, with 0.3.0 on the horizon of early Oct.

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

Yes, if you let me know what you want me to edit, I'll do it ASAP

Here we discussed only the derive macro name

Great, good to know. Thank you for the suggestion and everything up to now.

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

I've created a PR for this #122

If @nappa85 's version is preferred thats fine with me, just thought I'd share the work as a PR in case it can be used or to share any thoughts.

Let me know what you guys think

Thank you so much for the big PR. I think yours are very promising!

@nappa85 What's your view on this?

@acidic9 Can you show some more examples on the proposed format and annotation syntax (even if they are not implemented yet)?

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024

I'm not telling my version in better than @acidic9 one, but I'm already using mine in my projects, it's almost complete, at least for my use cases, and I made almost no changes since I created it 8 days ago

from sea-orm.

tqwewe avatar tqwewe commented on May 13, 2024

@nappa85 I didn't get a chance to get an example working with your code, I'm not sure how exactly to use it. Do you think you could briefly explain what the API looks like for your version?

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024

@nappa85 I didn't get a chance to get an example working with your code, I'm not sure how exactly to use it. Do you think you could briefly explain what the API looks like for your version?

you can find a working example in the tests folder of my repo https://github.com/nappa85/sea-orm-macro/blob/master/tests/it_works.rs

I can write some docs once we decided what has to be changed

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

Thank you for everyone's input here. We will think a bit and perhaps draft a design document.

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024

I've wrote a little readme to better explain the proc macro: https://github.com/nappa85/sea-orm-macro/blob/master/README.md

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

I've wrote a little readme to better explain the proc macro: https://github.com/nappa85/sea-orm-macro/blob/master/README.md

Thank you, this is extremely helpful!

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

Borrowing ideas from #122,

I think we can enhance the DeriveEntity macro:

#[derive(Copy, Clone, Default, Debug, DeriveEntity)]
#[sea_orm(schema_name = "public", table_name = "posts")]
pub struct Entity;

This will generate also the following:

impl EntityName for Entity {
    fn schema_name(&self) -> Option<&str> {
        Some("public")
    }

    fn table_name(&self) -> &str {
        "posts"
    }
}

This design, I think, will decouple the InsertModel (SimpleInput) / UpdateModel (SimpleUpdate) problem.

from sea-orm.

tqwewe avatar tqwewe commented on May 13, 2024

I like what you've descirbed here @tyt2y3.

The sea-orm-cli generates also:

impl RelationTrait for Relation {
    fn def(&self) -> RelationDef {
        match self {
            _ => panic!("No RelationDef"),
        }
    }
}

And

impl ActiveModelBehavior for ActiveModel {}

Are these necessary? And should they be expanded from a derive macro also, or manually implemented?

If a table has no relation def, perhaps instead of the panic it should just not implement it? I've seen a few places where panics in the SeaORM source code could be replaced with error types or just adjustments to the types to ensure these are not possible at compile time.

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

Relations

Similarly, we might also be able to simplify Relation definition a bit:

#[derive(EntityRelation)]
pub enum Relation {
    #[sea_orm(belongs_to = "super::cake::Entity", from = "Column::CakeId", to = "super::cake::Column::Id")]
    Cake,
}

auto generate the following:

impl RelationTrait for Relation {
    fn def(&self) -> RelationDef {
        match self {
            Self::Cake => Entity::belongs_to(super::cake::Entity)
                .from(Column::CakeId)
                .to(super::cake::Column::Id)
                .into(),
        }
    }
}

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

@nappa85 what's your thought on the proposed design so far?
(may be we should name the macro DeriveEntityModel to keep the convention with other macros)

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024

I've just read everything and I have no objections (aka "looks dope man!").
I've read in another issue (but actually I can't find it) about the ability to generate more than one Relation with the same Entity, maybe we should integrate that too, I've felt this limitation myself

To give an example, just think about a binary tree, you have left and right that are the same Entity, so you'll have

struct Model {
id: u64,
left: u64,
right: u64,
}

enum Relation {
Left,
Right,
}

impl RelationTrait for Relation {
    fn def(&self) -> RelationDef {
        match self {
            Relation::Left => Entity::belongs_to(Entity)
                .from(Column::Left)
                .to(Column::Id)
                .into(),
            Relation::Right => Entity::belongs_to(Entity)
                .from(Column::Right)
                .to(Column::Id)
                .into(),
        }
    }
}

impl Related<Entity> for Entity {
    fn to() -> RelationDef {
        Relation::Left.def()
    }
}

// ERROR conflicting impl for Related<Entity>
impl Related<Entity> for Entity {
    fn to() -> RelationDef {
        Relation::Right.def()
    }
}

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

@nappa85
That issue is #89, and basically the Linked trait has been introduced in 0.2.0

Can you open a PR with what you have got in sea-orm-macros for now, so we can work together?

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024

Can you open a PR with what you have got in sea-orm-macros for now, so we can work together?

Sure, give me a moment

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024

Ok, I've created #128

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024

That said, 3 more methods will be added:

fn default_value(self, v: V) where V: IntoValue { ... }
fn default_expr(self, expr: &str) { ... }
fn nullable(self) { ... }

Here you talk about adding those methods, are those already been added?

from sea-orm.

billy1624 avatar billy1624 commented on May 13, 2024

That said, 3 more methods will be added:

fn default_value(self, v: V) where V: IntoValue { ... }
fn default_expr(self, expr: &str) { ... }
fn nullable(self) { ... }

Here you talk about adding those methods, are those already been added?

Not yet added.

from sea-orm.

tqwewe avatar tqwewe commented on May 13, 2024

@tyt2y3 @billy1624 @nappa85 Please see my updated PR #122.

I've updated the whole thing to match the specs listed here, with few changes such as the attribute being #[sea( ... )] instead of #[sea_orm( ... )].

Please take a look and let me know your thoughts, I've explained in detail every change made in the PR :)

from sea-orm.

tqwewe avatar tqwewe commented on May 13, 2024

That said, 3 more methods will be added:

fn default_value(self, v: V) where V: IntoValue { ... }
fn default_expr(self, expr: &str) { ... }
fn nullable(self) { ... }

Here you talk about adding those methods, are those already been added?

Not yet added.

Although, there already exists: .unique(), .null(), .indexed() right?

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

@tyt2y3 @billy1624 @nappa85 Please see my updated PR #122.

Sure. I will definitely take a close look.

Although, there already exists: .unique(), .null(), .index() right?

Yes. SeaQuery already has the default_value but not default_expr. I think we need to update SeaQuery first.

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024

Although, there already exists: .unique(), .null(), .indexed() right?

So is it the old null or the new nullable?
Just to disambiguate...

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

Yes, I think we should use the nullable method for consistency.

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024

Yes, I think we should use the nullable method for consistency.

Perfect, so the macro code is already aligned

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

I am done for today. Feel free to peek at the current status.

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

I am thinking, whether DeriveEntityModel should automatically derive DeriveModel and DeriveActiveModel, to make it less verbose.

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024

I am thinking, whether DeriveEntityModel should automatically derive DeriveModel and DeriveActiveModel, to make it less verbose.

Could be a good idea

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024

I am thinking, whether DeriveEntityModel should automatically derive DeriveModel and DeriveActiveModel, to make it less verbose.

I've made some tests about it, maybe I'm wrong, but it seems that a derive macro can't edit the original struct, to do so you need a proc-macro.

I've tried with this code, inside DeriveEntityModel macro:

    attrs.push(Attribute {
        pound_token: Pound(Span::call_site()),
        style: AttrStyle::Outer,
        bracket_token: Bracket(Span::call_site()),
        path: Path {
            leading_colon: None,
            segments: {
                let mut temp = Punctuated::new();
                temp.push(PathSegment {
                    ident: Ident::new("derive", Span::call_site()),
                    arguments: PathArguments::None,
                });
                temp
            },
        },
        tokens: quote! { DeriveModel, DeriveActiveModel },
    });

from sea-orm.

tqwewe avatar tqwewe commented on May 13, 2024

Rather than modifying the derive attribute of the struct itself, it's probably better to just reuse the code of DeriveModel and DeriveActiveModel.

For example, if they both use the struct approach, then you could just call expand them directly.

struct DeriveEntityModel {
    derive_model: DeriveModel,
    derive_active_model: DeriveActiveModel,
    ...
}

impl DeriveEntityModel {
    fn new(input: syn::DeriveInput) -> syn::Result<Self, Error> {
        ...
    
        Ok(DeriveEntityModel {
            derive_model: DeriveModel::new(input)?,
            derive_active_model: DeriveActiveModel::new(input)?,
            ...
        })
     }
     
     fn expand(&self) -> syn::Result<TokenStream> {
         let expanded_derive_model = self.derive_model.expand()?;
         let expanded_derive_active_model = self.derive_active_model.expand()?;
         ...
         
         Ok(TokenStream::from_iter([
            expanded_derive_model,
            expanded_derive_active_model,
            ...
        ]))
     }
}

I hope that makes sense.

from sea-orm.

billy1624 avatar billy1624 commented on May 13, 2024

Oh I just committed 54bb358 for this, feel free to comments :)

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024

Oh I just committed 54bb358 for this, feel free to comments :)

Are we ok with the macro always deriving the other macros?
All other features, like deriving PrimaryKey, were controlled by an attribute.

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub name: String,
#[sea_orm(column_type = "Text", nullable)]
pub notes: Option<String>,
}

@nappa85 I discovered a strange behavior. when column_type is specified, nullable can no longer be inferred from the Option<_> type

So the following is correct:

#[sea_orm(column_type = "Text", nullable)]
pub notes: Option<String>,

But the following is wrong:

#[sea_orm(column_type = "Text")]
pub notes: Option<String>,

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::bakery::Entity",
from = "Column::BakeryId",
to = "super::bakery::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)]
Bakery,
}

Our current DeriveRelation is quite 'copy & paste' now.

I am thinking if instead of

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
    #[sea_orm(
        belongs_to = "super::bakery::Entity",
        from = "Column::BakeryId",
        to = "super::bakery::Column::Id",
        on_update = "Cascade",
        on_delete = "Cascade"
    )]
    Bakery,
}

we do

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
    #[sea_orm(
        belongs_to = "bakery",
        from = "bakery_id",
        to = "bakery.id",
        on_update = "cascade",
        on_delete = "cascade"
    )]
    Bakery,
}

But is this 'too much'?

from sea-orm.

nappa85 avatar nappa85 commented on May 13, 2024

@nappa85 I discovered a strange behavior. when column_type is specified, nullable can no longer be inferred from the Option<_> type

Yes, it's kind-of wanted, IMHO if you're specifying the type, you've to specify it entirely

from sea-orm.

tqwewe avatar tqwewe commented on May 13, 2024

I agree that it's becoming a little bit too much magic. Perhaps the entire DeriveRelation can just be scrapped as it just implements RelationTrait..? I think it just makes sense at this point to let the user write their own implementation of it.

from sea-orm.

tyt2y3 avatar tyt2y3 commented on May 13, 2024

Yes, it's kind-of wanted, IMHO if you're specifying the type, you've to specify it entirely

Understood

I agree that it's becoming a little bit too much magic. Perhaps the entire DeriveRelation can just be scrapped as it just implements RelationTrait..? I think it just makes sense at this point to let the user write their own implementation of it.

um... it does save a few lines and another impl block, innit?

I think it's becoming too much magic, what if the other entity isn't on the the parent module but it's on another crate?
The first version is better, more explicit

Great, then seemingly everything is set now

from sea-orm.

github-actions avatar github-actions commented on May 13, 2024

🎉 Released In 0.12.1 🎉

Thank you everyone for the contribution!
This feature is now available in the latest release. Now is a good time to upgrade!
Your participation is what makes us unique; your adoption is what drives us forward.
You can support SeaQL 🌊 by starring our repos, sharing our libraries and becoming a sponsor ⭐.

from sea-orm.

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.