Skip to main content
Glama
models.ex4.14 kB
defmodule TestRepo.Models do @moduledoc """ Models module demonstrating various Elixir patterns including structs, protocols, and behaviours. """ defprotocol Serializable do @doc "Convert model to map representation" def to_map(model) end defmodule User do @type t :: %__MODULE__{ id: String.t(), name: String.t() | nil, email: String.t(), roles: list(String.t()) } defstruct [:id, :name, :email, roles: []] @doc """ Creates a new user. ## Examples iex> TestRepo.Models.User.new("1", "Alice", "alice@example.com") %TestRepo.Models.User{id: "1", name: "Alice", email: "alice@example.com", roles: []} """ def new(id, name, email, roles \\ []) do %__MODULE__{id: id, name: name, email: email, roles: roles} end @doc """ Checks if user has a specific role. """ def has_role?(%__MODULE__{roles: roles}, role) do role in roles end @doc """ Adds a role to the user. """ def add_role(%__MODULE__{roles: roles} = user, role) do %{user | roles: [role | roles]} end end defmodule Item do @type t :: %__MODULE__{ id: String.t(), name: String.t(), price: float(), category: String.t() } defstruct [:id, :name, :price, :category] @doc """ Creates a new item. ## Examples iex> TestRepo.Models.Item.new("1", "Widget", 19.99, "electronics") %TestRepo.Models.Item{id: "1", name: "Widget", price: 19.99, category: "electronics"} """ def new(id, name, price, category) do %__MODULE__{id: id, name: name, price: price, category: category} end @doc """ Formats price for display. """ def display_price(%__MODULE__{price: price}) do "$#{:erlang.float_to_binary(price, decimals: 2)}" end @doc """ Checks if item is in a specific category. """ def in_category?(%__MODULE__{category: category}, target_category) do category == target_category end end defmodule Order do alias TestRepo.Models.{User, Item} @type t :: %__MODULE__{ id: String.t(), user: User.t(), items: list(Item.t()), total: float(), status: atom() } defstruct [:id, :user, items: [], total: 0.0, status: :pending] @doc """ Creates a new order. """ def new(id, user, items \\ []) do total = calculate_total(items) %__MODULE__{id: id, user: user, items: items, total: total} end @doc """ Adds an item to the order. """ def add_item(%__MODULE__{items: items} = order, item) do new_items = [item | items] %{order | items: new_items, total: calculate_total(new_items)} end @doc """ Updates order status. """ def update_status(%__MODULE__{} = order, status) do %{order | status: status} end defp calculate_total(items) do Enum.reduce(items, 0.0, fn item, acc -> acc + item.price end) end end # Protocol implementations defimpl Serializable, for: User do def to_map(%User{id: id, name: name, email: email, roles: roles}) do %{id: id, name: name, email: email, roles: roles} end end defimpl Serializable, for: Item do def to_map(%Item{id: id, name: name, price: price, category: category}) do %{id: id, name: name, price: price, category: category} end end defimpl Serializable, for: Order do def to_map(%Order{id: id, user: user, items: items, total: total, status: status}) do %{ id: id, user: Serializable.to_map(user), items: Enum.map(items, &Serializable.to_map/1), total: total, status: status } end end @doc """ Factory function to create a sample user. """ def create_sample_user do User.new("sample", "Sample User", "sample@example.com", ["user"]) end @doc """ Factory function to create a sample item. """ def create_sample_item do Item.new("sample", "Sample Item", 9.99, "sample") end end

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ryota-murakami/serena'

If you have feedback or need assistance with the MCP directory API, please join our Discord server