Forem

crespire
crespire

Posted on

6 1 1

Hooking in to Devise controller actions

Devise is a fantastic authentication gem in the Rails ecosystem that I'm learning more about every day!

I wanted to share how I was able to solve a problem effectively after reading some Devise source code, as it might come in handy for others.

The problem

I was working on a project using the Devise addition invitable and I needed a way to update a user's profile after they accepted an invite so I could set the slug based on their name. When the user invite is created, we use a generic value as a filler for the name.

I had originally used an ActiveRecord callback, but this felt clunky. Not only was it difficult to understand what it was doing, the side effect of the callback happened on the Profile model! That would be hard to debug if it was your first time working on the app and something was going wrong with the Profile's slug generation.

I began searching for ways to do what I wanted without callbacks and I decided to take a look at the Devise controllers source code.

The solve

It turns out, Devise anticipates that you might want to access a resource while it's doing its thing, and so almost every Devise controller action has a line like this:

yield resource if block_given?
Enter fullscreen mode Exit fullscreen mode

This is fantastic! Because we often inherit from the base Devise controllers, what this line does is let you access the resource under operation if you pass in a block:

# sample controller
class Users::RegistrationsController < Devise::RegistrationsController
  def update
    super { |resource| ... }
  end
end
Enter fullscreen mode Exit fullscreen mode

This was a game changer! I now had a great way to update the profile's slug with the user's provided name:

# app/controllers/users/registrations_controller.rb
def update
  super { |user| user.profile.update(slug: user.full_name.parameterize) }
end
Enter fullscreen mode Exit fullscreen mode

Just like that, I was able to get rid of an ActiveRecord callback! So, if you ever need to access the resource to do something inside a Devise controller, this is your ticket.

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more

Top comments (1)

Collapse
 
joshdevhub profile image
Josh Smith •

Awesome post 💪

Learning how to read library source code can be such an underrated skill

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay