GenieFramework / SearchLight.jl

ORM layer for Genie.jl, the highly productive Julia web framework
https://genieframework.com
MIT License
139 stars 16 forks source link

Callbacks API #31

Open p-gw opened 3 years ago

p-gw commented 3 years ago

Describe the bug If callback fields are specified in the model, entries cannot be saved to the database. The save! function expects the callback fields of the struct as columns in the database table.

Error stacktrace

[ Info: 2020-12-01 19:17:36 Do something before saving
[ Info: 2020-12-01 19:17:36 INSERT INTO callbacks ( "title", "indicator", "created_at", "before_save", "after_save" ) VALUES ( E'testing', true, E'2020-12-01T19:17:36.376', E'#4', E'#5' ) RETURNING id
[error | LibPQ]: UndefinedColumn: ERROR:  column "before_save" of relation "callbacks" does not exist
LINE 1: ...O callbacks ( "title", "indicator", "created_at", "before_sa...
                                                             ^
ERROR: UndefinedColumn: ERROR:  column "before_save" of relation "callbacks" does not exist

To reproduce

  1. Create a model containing callbacks, e.g.

    @kwdef mutable struct Callback <: AbstractModel
    id::DbId = DbId()
    title::String = ""
    indicator::Bool = true
    created_at::String = string(Dates.now())
    # callbacks
    before_save::Function = (m::Callback) -> begin
    @info "Do something before saving"
    end
    after_save::Function = (m::Callback) -> begin
    @info "Do something after saving"
    end
    end
  2. Save entry to database

julia> Callback(title = "testing") |> save!

This will result in the above UndefinedColumn error.

Expected behavior The expected behaviour is to ignore the callback fields (before_save and after_save) of the struct when creating entries in the database.

FrankUrbach commented 3 years ago

Hallo Phillip Which adapter for storing your data you use? Some things are regulated within the adapter so it is important for a fast solution to know which one you use. Edit: I see in the stacktrace you use the PostgeSQL-adapter. Best Frank

p-gw commented 3 years ago

I've tried it with both the PostgreSQL adapter and the SQLite adapter with the same result.

FrankUrbach commented 3 years ago

It doesn't matter which one for solving this problem. Only when you have a problem with a task in one ore the other adapter for production purposes it should be the right adapter to begin with. :-)

FrankUrbach commented 3 years ago

@Adrian, @Phillip There are two different approaches for dealing with functions such as before_save, after_save and so on. First: The implementation like it is done for now in SearchLight by using a field in the model struct and dealing then with them. Second: We could implement this functions as a generic function, prepare fallback functions for this and let the user of SearchLIght choose whether he/she implement these functions for the type in the model. For now I defined the fields which are reserved for this actions in an array and filter them on the right place. You will find the corresponding source file of src/SearchLight.jl attached to this comment.

Feel free to contact me any time if you have comments, wishes or hints.

SearchLight.jl.zip

Best Frank P.S. I also removed an error from the save! chain.

essenciary commented 3 years ago

I think the callbacks API needs to be updated.