Skip to content

Instantly share code, notes, and snippets.

@jschoch
Last active August 29, 2015 13:56
Show Gist options
  • Save jschoch/8848204 to your computer and use it in GitHub Desktop.
Save jschoch/8848204 to your computer and use it in GitHub Desktop.
Ecto gettign started with associations
First step is to create a new project
mix new ecto_quickstart
cd ecto_quickstart/
Next edit your ./mix.exs to include the dependencies for ecto
defmodule EctoQuickstart.Mixfile do
use Mix.Project
def project do
[ app: :ecto_quickstart,
version: "0.0.1",
elixir: "~> 0.12.3",
deps: deps ]
end
# Configuration for the OTP application
def application do
[mod: { EctoQuickstart, [] }]
end
# Returns the list of dependencies in the format:
# { :foobar, git: "https://github.com/elixir-lang/foobar.git", tag: "0.1" }
#
# To specify particular versions, regardless of the tag, do:
# { :barbat, "~> 0.1", github: "elixir-lang/barbat" }
defp deps do
#### update for ecto deps here ####
[{ :postgrex, github: "ericmj/postgrex" },
{ :ecto, github: "elixir-lang/ecto" }]
end
end
Now use mix to grab your dependencies
mix deps.get
Now we can use the mix tasks included to make an empty repo
mix ecto.gen.repo Repo
We need to create a database that maps to the Repo we just mixed, refer to the psql docs for help here if you don't understand this.
sudo -u nobody /usr/local/pgsql/bin/createdb ecto_quickstart_repo_dev
Edit the repo in lib/repo.ex
defmodule Repo do
use Ecto.Repo, adapter: Ecto.Adapters.Postgres, env: Mix.env
@doc "The URL to reach the database."
def url(:dev) do
#### update your pg url here ####
"ecto://nobody@localhost/ecto_quickstart_repo_dev"
end
def url(:test) do
"ecto://user:pass@localhost/ecto_quickstart_repo_test?size=1&max_overflow=0"
end
def url(:prod) do
"ecto://user:pass@localhost/ecto_quickstart_repo_prod"
end
@doc "The priv directory to load migrations and metadata."
def priv do
app_dir(:ecto_quickstart, "priv/repo")
end
end
Update the supervisor stub
defmodule EctoQuickstart.Supervisor do
use Supervisor.Behaviour
def start_link do
#### replace start_link method ####
:supervisor.start_link({ :local, __MODULE__ }, __MODULE__, [])
end
def init([]) do
#### replace the init here ####
tree = [ worker(Repo, []) ]
supervise(tree, strategy: :one_for_all)
end
end
now edit lib/ecto_quickstart.ex
defmodule EctoQuickstart do
use Application.Behaviour
# See http://elixir-lang.org/docs/stable/Application.Behaviour.html
# for more information on OTP Applications
def start(_type, _args) do
EctoQuickstart.Supervisor.start_link
end
end
#### add models below ####
defmodule Parent do
use Ecto.Model
queryable "parent" do
has_many :children, Child
field :name, :string
end
end
defmodule Child do
use Ecto.Model
queryable "child" do
field :name, :string
belongs_to :parent, Parent
end
end
Mix a migration stub
mix ecto.gen.migration Repo create_parent_child
edit the migration (time stamp will change for yours) priv/repo/migrations/20140206171819_create_parent_child.exs
defmodule Repo.Migrations.CreateParentChild do
use Ecto.Migration
def up do
#### add table create here, parent must be created first ####
["create table if not exists parent(id serial primary key,name text)","create table if not exists child(id serial primary key, name text,parent_id integer references parent(id))"]
end
def down do
#### add drop here, the order matters due to the association ####
[ "drop table child","drop table parent" ]
end
end
Mix the data structure in the db
mix ecto.migrate Repo
launch iex:
iex -S mix run
Run the following commands in iex, they should create a parent, and child that is associated. It will then commit them to the db and query them back out.
parent = Parent.new(name: "foo")
Repo.create(parent)
child = Child.new(name: "bar", parent_id: 1)
Repo.create(child)
parent = Repo.get(Parent,1)
Repo.all(parent.children)
c = c.name("unf")
Repo.update(c)
Repo.all(parent.children)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment