Ecto Observable adds observable functionality to Ecto Repo.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
config
lib/observable
priv/test_repo/migrations
test
.formatter.exs
.gitignore
.travis.yml
LICENSE
README.md
mix.exs
mix.lock

README.md

Ecto Observable

Build Status Ecto.Observable Version

Ecto Observable adds "observable" functionality to Ecto.Repo.

Installation

The package can be installed by adding ecto_observable to your list of dependencies in mix.exs:

def deps do
  [
    {:ecto_observable, "~> 0.3.1"}
  ]
end

Documentation

See HexDocs for additional documentation.

Getting Started

Lets say we have a Post schema. Each post can have many topics. Users can subscribe to topics. Whenever a post is created, we are responsible for informing the subscribed users.

Given the above, lets setup our new "observable" repo.

defmodule Repo do
  use Ecto.Repo, otp_app: :my_app
  use Observable.Repo
end

We have defined our repo as normal - but with the addition of use Observable.Repo to bring in the required observable functionality.

Lets create our new observer now.

defmodule SubscribersObserver do
  use Observable, :observer

  # Lets ignore posts that dont have any topics.
  def handle_notify({:insert, %Post{topics: []}}) do
    :ok
  end

  def handle_notify({:insert, %Post{topics: topics}}) do
    # Do work required to inform subscribed users.
  end

  # Defined for the sake of example. Ignore me!
  def handle_notify({:update, [old_post, new_post]}) do
    :ok
  end

  # Defined for the sake of example. Ignore me!
  def handle_notify({:delete, post}) do
    :ok
  end
end

Now that we have our observer set up, lets modify our Post schema to support notifying our observers.

defmodule Post do
  use Ecto.Schema
  use Observable, :notifier

  schema "posts" do
    field(:title, :string)
    field(:body, :string)
    field(:topics, {:array, :string}, default: [])
  end

  observations do
    action(:insert, [SubscribersObserver])
    action(:update, [SubscribersObserver])
    action(:delete, [OtherObserverOne, OtherObserverTwo]) # Defined for the sake of example.
  end
end

Now that we are starting to use "observable" behaviour, we must modify the way in which we insert posts with our repo.

def create_post(params \\ %{}) do
  %Post{}
  |> Post.changeset(params)
  |> Repo.insert_and_notify()
end

Our users will now be informed of any new posts with topics they are interested in!

The same behaviour can be replicated for :update and :delete actions.

Repo.update_and_notify(post)
Repo.delete_and_notify(post)

Each of the new observer-based actions also has equivalent bang function available that will raise on error.

Repo.insert_and_notify!(post)