Repo, Changesets, and Queries
Use `Ecto.Repo` for database interactions, `Changesets` for data validation, and build queries with `Ecto.Query`.
Ecto.Repo: Database Gateway
In Elixir, Ecto.Repo is your primary interface for interacting with your database. Think of it as the central hub that handles all your database operations.
It provides functions for inserting, updating, deleting, and querying records, abstracting away the specifics of the underlying database technology.
- Connects your Elixir application to the database.
- Manages database transactions.
- Executes Ecto queries.
Saving Data with Repo.insert
To add new data to your database, you'll use Ecto.Repo.insert/2. This function takes a changeset (which we'll cover next) and attempts to save it as a new record.
If successful, it returns {:ok, record}; otherwise, it returns {:error, changeset} with validation errors.
defmodule MyApp.Product do
use Ecto.Schema
import Ecto.Changeset
schema "products" do
field :name, :string
field :price, :decimal
field :stock, :integer, default: 0
timestamps()
end
def changeset(product, attrs) do
product
|> cast(attrs, [:name, :price, :stock])
|> validate_required([:name, :price])
|> validate_number(:price, greater_than: 0)
|> validate_number(:stock, greater_than_or_equal_to: 0)
end
end
defmodule MyApp.SimulatedRepo do
alias MyApp.Product
def insert(changeset) do
if Ecto.Changeset.valid?(changeset) do
data = Ecto.Changeset.apply_action(changeset, :insert)
# Simulate successful insert with a mock ID and timestamps
{:ok, %Product{data | id: 1, inserted_at: NaiveDateTime.utc_now(), updated_at: NaiveDateTime.utc_now()}}
else
{:error, changeset}
end
end
end
defmodule InsertExample do
alias MyApp.{Product, SimulatedRepo}
def run() do
# Prepare product attributes
attrs = %{name: "Elixir Book", price: Decimal.new("39.99"), stock: 100}
# Create a changeset
changeset = Product.changeset(%Product{}, attrs)
# Simulate inserting the product
case SimulatedRepo.insert(changeset) do
{:ok, product} ->
IO.puts "Successfully inserted product:"
IO.inspect product
{:error, changeset} ->
IO.puts "Failed to insert product:"
IO.inspect Ecto.Changeset.errors(changeset)
end
end
end
# To run this, execute: elixir -e "InsertExample.run()"All lessons in this course
- Ecto Schema and Database Migrations
- Repo, Changesets, and Queries
- Associations and Embedded Schemas
- Transactions and Ecto.Multi