Rob Lacey

Brighton, UK - contact@robl.me

Software Engineer specialising in Ruby on Rails. I do occasional freelance work, I love working for SARD JV Ltd, they are awesome and give me my pocket money every month. By all means dangle a carrot.


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.