belaustegui
Adding typespect to an Ecto Schema
I have an Ecto schema and I am wondering about how to represent it in typespecs.
Suppose that my schema is like this:
defmodule User do
use MyApp.Model
schema "users" do
field :name, :string
field :email, :string
timestamps
end
end
Which would be the best way to refer to this struct in my specs? Currently I am doing something like:
@spec my_function(String.t) :: %User{}
But I’m thinking that I could add a @type t :: %__MODULE__{user: String.t, email: String.t} declaration to my User struct and change the specs to something like:
@spec my_function(String.t) :: User.t
Which alternative would be the best? And why?
First Post!
PragTob
I believe @type t ... is the convention to define the type of module and hence should be preferred - it’s the first thing I’d try in an application. Also if you define the required keys like you showed, then you don’t have to repeat that knowledge everywhere and the source of truth lives in Schema.t
Most Liked
mgwidmann
I’d say if Ecto does not already setup a typespec for your schema when it defines the struct, then I’d consider that a bug. This should happen automatically IMO.
ggerico
Could someone check if the LOC below are flawless, especially:
- the virtual field
- the associations
teacher_id: integer() or should it be teacher: Teacher.t()
user_id: integer() or should it be user: User.t()
# user.ex
@type t :: %__MODULE__{
id: integer,
email: String.t(),
name: String.t(),
phone: String.t(),
credential: Credential.t(),
teacher_id: integer,
student_id: integer,
inserted_at: NaiveDateTime.t(),
updated_at: NaiveDateTime.t()
}
schema "users" do
field(:email, :string)
field(:name, :string)
field(:phone, :string)
has_one(:credential, Credential)
belongs_to(:teacher, Teacher)
belongs_to(:student, Student)
timestamps()
end
# credential.ex
@type t :: %__MODULE__{
password: String.t(),
password_hash: String.t(),
user_id: integer,
inserted_at: NaiveDateTime.t(),
updated_at: NaiveDateTime.t()
}
schema "credentials" do
field(:password_hash, :string)
# Virtual Fields
field(:password, :string, virtual: true)
belongs_to(:user, User)
timestamps()
end
# teacher.ex
@type t :: %__MODULE__{
id: integer,
experience: String.t(),
user: User.t(),
students: [ Student.t() ],
subjects: [ Subject.t() ],
inserted_at: NaiveDateTime.t(),
updated_at: NaiveDateTime.t()
}
schema "teachers" do
field(:experience, :integer, default: 1)
has_one(:user, User)
has_many(:student, Student)
has_many(:subject, Subject)
timestamps()
end
toraritte
Custom types should be implemented using Ecto.Type behaviour, so maybe it would be possible to bake this into any new custom type?
There is also a relevant issue in the ejpcmac/typed_struct repo.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex









