Intuitively, I thought that a slice repo, like this one
# slices/auth/repos/user_repo
module Auth
module Repos
class UserRepo < Auth::DB::Repo
def all
users.to_a
end
end
end
end
would use the top-level struct class, if the slice has no user-struct defined. But that’s not the case. The top-level struct is only used if the struct_namespace is explicitly overwritten. Is this desired behavior?
module Auth
module Repos
class UserRepo < Auth::DB::Repo
struct_namespace InhouseGate::Structs
def all
users.to_a
end
end
end
end
By top-level I mean app-level structs. In my opinion, it makes sense to define structs at app level and then share them at the slice repos, if they are not defined at slice-level. In the above case, I created the user-struct at app level and thought it would be used by the slice user-repo out of the box.
It’s not a big issue. I’m just curious if it’s intentional.
Yes, I would say that it is intentional. I will quote from the docs that I’m working on:
A Struct is not a permanent abstraction of a piece of data: it is a momentary projection of the data you requested. This means that instead of a User model that fills every role you need of a user, you could project user data as a Credential for authentication, a Role for authorization, a Visitor for displaying their identity on the page. Every projection can serve a specific purpose, and contain exactly the information you need and nothing more.
What this is intended to get across is that having a singular User model that collects every bit of logic pertaining to users is an anti-pattern. Redefining your User struct is actually desirable, because it makes you think about what you really need for that context.
However, if there is standard presentation logic that you want to share across all Slices, I think this is the most straightforward solution:
# app/structs/user.rb
module InhouseGate
module Structs
class User < Hanami::DB::Struct
def name = "#{given_name} #{family_name}"
end
end
end
# slices/auth/structs/user.rb
module Auth
module Structs
class User < InhouseGate::User
end
end
end
Slices don’t directly manage constants. The dependency graph between slices is based on container keys, and struct classes are an exception to this because they are not containerized.