Rob Lacey

Brighton, UK - contact@robl.me

Software Engineer working since 2008 with Ruby / Ruby on Rails, love a bit of Elixir / Phoenix. I also poke through other people's code and make PRs for OpenSource Ruby projects that sometimes make it. Currently working at Juniper Education making code for UK schools.


Phoenix and MongoDB

Looks like Ecto 3 compatabilty for mongo-ecto was committed 4 days ago. So trying to flip over my default PostgreSQL setup to MongoDB.

diff --git a/config/dev.exs b/config/dev.exs
index 72122a0..07fb393 100644
--- a/config/dev.exs
+++ b/config/dev.exs
@@ -1,13 +1,18 @@
 import Config
 
 # Configure your database
+# config :dungeon, Dungeon.Repo,
+#   username: "dungeon",
+#   password: "",
+#   database: "dungeon_dev",
+#   hostname: "localhost",
+#   show_sensitive_data_on_connection_error: true,
+#   pool_size: 10
+
 config :dungeon, Dungeon.Repo,
-  username: "dungeon",
-  password: "",
+  adapter: Mongo.Ecto,
   database: "dungeon_dev",
-  hostname: "localhost",
-  show_sensitive_data_on_connection_error: true,
-  pool_size: 10
+  hostname: "localhost"
 
 # For development, we disable any cache and enable
 # debugging and code reloading.
diff --git a/lib/dungeon/repo.ex b/lib/dungeon/repo.ex
index 09502cf..df8c03b 100644
--- a/lib/dungeon/repo.ex
+++ b/lib/dungeon/repo.ex
@@ -1,5 +1,8 @@
 defmodule Dungeon.Repo do
+  # use Ecto.Repo,
+  #   otp_app: :dungeon,
+  #   adapter: Ecto.Adapters.Postgres
   use Ecto.Repo,
     otp_app: :dungeon,
-    adapter: Ecto.Adapters.Postgres
+    adapter: Mongo.Ecto
 end
 
diff --git a/mix.exs b/mix.exs
index bcc220c..ce79a70 100644
--- a/mix.exs
+++ b/mix.exs
@@ -20,7 +20,7 @@ defmodule Dungeon.MixProject do
   def application do
     [
       mod: {Dungeon.Application, []},
-      extra_applications: [:logger, :runtime_tools]
+      extra_applications: [:logger, :mongodb_ecto, :ecto, :runtime_tools]
     ]
   end
 
@@ -35,8 +35,9 @@ defmodule Dungeon.MixProject do
     [
       {:phoenix, "~> 1.6.2"},
       {:phoenix_ecto, "~> 4.4"},
-      {:ecto_sql, "~> 3.6"},
-      {:postgrex, ">= 0.0.0"},
+      # {:ecto_sql, "~> 3.6"},
+      {:mongodb_ecto, github: "elixir-mongo/mongodb_ecto"},
+      # {:postgrex, ">= 0.0.0"},
       {:phoenix_html, "~> 3.0"},
       {:phoenix_live_reload, "~> 1.2", only: :dev},
       {:phoenix_live_view, "~> 0.16.0"},
  
Ok, this seemed plenty easier than I was expecting.
iex(1)> Dungeon.Repo.all(Dungeon.Room)
[debug] QUERY OK db=1.8ms decode=1.3ms idle=1930.8ms
FIND coll="rooms" query=[{"$query", []}, {"$orderby", %{}}] projection=%{_id: true, name: true, x: true, y: true} [[{"$query", []}, {"$orderby", %{}}], %{_id: true, name: true, x: true, y: true}]
[]

Not a Dungeon in sight.

iex(2)> w = %Dungeon.Room{x: 1, y: 1} 
%Dungeon.Room{
  __meta__: #Ecto.Schema.Metadata<:built, "rooms">,
  id: nil,
  name: nil,
  x: 1,
  y: 1
}
iex(3)> Dungeon.Repo.insert!(w)
[debug] QUERY OK db=96.8ms idle=1253.4ms
COMMAND [insert: "rooms", documents: [[_id: #BSON.ObjectId<619c493af7fdf5aad1189f38>, x: 1, y: 1]], writeConcern: %{}] [[insert: "rooms", documents: [[_id: #BSON.ObjectId<619c493af7fdf5aad1189f38>, x: 1, y: 1]], writeConcern: %{}]]
%Dungeon.Room{
  __meta__: #Ecto.Schema.Metadata<:loaded, "rooms">,
  id: "619c493af7fdf5aad1189f38",
  name: nil,
  x: 1,
  y: 1
}
iex(4)> Dungeon.Repo.all(Dungeon.Room)
[debug] QUERY OK db=0.4ms idle=422.0ms
FIND coll="rooms" query=[{"$query", []}, {"$orderby", %{}}] projection=%{_id: true, name: true, x: true, y: true} [[{"$query", []}, {"$orderby", %{}}], %{_id: true, name: true, x: true, y: true}]
[
  %Dungeon.Room{
    __meta__: #Ecto.Schema.Metadata<:loaded, "rooms">,
    id: "619c493af7fdf5aad1189f38",
    name: nil,
    x: 1,
    y: 1
  }
]
Now to build an interface to populate this damn thing.