wemgl

wemgl

I’m working on an app that uses Pow to handle user authentication. I was able to get it working by following the documentation, but I ran into an issue that I don’t see a clear solution for.

The application is for a subscription service where new users are given a free trial after signing up. I use Pow to create the user, which works fine. Now, I’m trying to associate the newly created user with a subscription using the controller callback feature from the Phoenix controllers section of the README. Here’s my implementation so far:

defmodule AddSubscription.Phoenix.ControllerCallbacks do
  use Pow.Extension.Phoenix.ControllerCallbacks.Base

  require Logger

  @impl true
  def before_respond(Pow.Phoenix.RegistrationController, :create, {:ok, user, conn}, _config) do
    Logger.debug("user registration before_respond: #{inspect(user)}")
    with {:ok, user} <- Trumpet.insert_subscription(%{user_id: user.id}) do
      {:ok, user, conn}
    end
  end
end

I’ve also written a controller test to exercise the behavior works as intended:

defmodule Pow.Phoenix.RegistrationControllerTest do
  use TrumpetWeb.ConnCase

  describe "POST /registration" do
    test "creates a user with a subscription", %{conn: conn} do
      email = "wembley.gl@gmail.com"
      post(
        conn,
        "/registration",
        %{
          user: %{
            email: email,
            password: "test1234567890",
            confirm_password: "test1234567890",
          }
        }
      )
      user = Trumpet.get_user_by_email_with_subscription(email)
      assert user.subscription
      assert Trumpet.Subscription.trial?(user.subscription)
    end
  end
end

The user creation works as expected, but the controller callback isn’t firing, so the assertion for user.subscription fails. I’ve taken a look at the Extensions section for Pow, from here, and looked at the implementation for other extensions, like PowPasswordReset, and it looks like an extension should be implemented as a library application, is that right? Also, how do I configure Pow to register an extension once it’s created? I apologize if this is in the documentation and I’m missing it.

Showing Posts 1 to 5

danschultzer

danschultzer

Pow Core Team

The callbacks is the wrong place to deal with this. You would want it to be inserted in a transaction so if the subscription insert fails, the user won’t be created. There’re multiple ways to deal with it, but if all users inserted needs to have a subscription created along it, then I would keep it simple and just deal with it in the user changeset:

defmodule MyApp.Users.User do
  use Ecto.Schema
  use Pow.Ecto.Schema

  schema "users" do
    has_one :subscription, MyApp.Users.Subscription

    pow_user_fields()

    timestamps()
  end

  def changeset(user_or_changeset, attrs) do
    user
    |> pow_changeset(attrs)
    |> maybe_add_subscription()
  end

  defp maybe_add_subscription(changeset) do
    case Ecto.get_meta(changeset.data, :state) do
      :built  -> add_subscription(changeset)
      :loaded -> changeset
    end
  end
  
  defp add_subscription(changeset) do
    Ecto.Changeset.cast_assoc(changeset, :subscription, with: &MyApp.Users.Subscription.changeset/2)
  end
end

If you need more control over the flow, then I would either set up a custom controller and/or custom context module.

(Also, as you guessed the controller callbacks module you’ve set up is only for custom extensions)

wemgl

wemgl OP

Thanks for the quick response. You make a valid point. I was caught up trying to leverage the functionality in Pow, that I forgot that I was able to make modifications to the User changeset directly, since all I did to add the Pow support was add pow_user_fields and the various use macros to bring in functions.

tenzil

tenzil

Hi @danschultzer, I was planning on adding a referral code in Login form, i generated the templates and added referral_code as text field, in the generated registration form. I have few doubts with the custom controllers
(The ask is): I want to add this referral code only on registration controller, in a transactional way. if code given , then i check presence of code and finally create user. If code not given, i directly create user.
I use pow_assent. I have read about invitation extension but i want to go with my own.

Doubts:

  1. I want to modify only create action of registration controller. Do i need to modify the routes as well?
  2. Do i need to add all action for both registration, session controllers and point their routes as mentioned in Custom controllers — Pow v1.0.11.
  3. Is there a way to overwrite only create action of registration controller?
danschultzer

danschultzer

Pow Core Team

There is a duplicate thread that I answered this in: POW: Custom controller doubts - #2 by danschultzer

tenzil

tenzil

Yes, looks like there was a network issue, i deleted this thread before creating a new one. but i think elixir-forum runs thread deletion in a background job.

Thanks again @danschultzer, I will try those steps and yet you know how it went in POW: Custom controller doubts

— All posts loaded —

Where Next? Top

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
water
I’m aware of 2 such projects, are there others? git: GitHub - team-alembic/realworld: A fullstack Phoenix LiveView application with back...
New
katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
peck
Hi everyone. My team and I have been working on a fairly modest app based around video streaming and chat, but we’ve landed a customer t...
New
bradley
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
unaware8150
Hello folks! So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
Alvinkariuki
How Can I Optimise Compile Time Dependencies I have been building an elixir application for about 2 years now. Many modules and files ha...
New

Other Trending Topics Top

mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews