►
Description
Discussing the newly-merge styleguide recommendation to avoid Rails callbacks: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125836
Specifically as it relates to an in-progress MR that adds a callback: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/127497#note_1489574714
We refactored this callback into a service class, draft MR: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/128215
A
C
B
It's
a
little
bit
so
yeah
there's
some
testing
notes.
Here
for
staging
and
I
have
basically
become
stuck
on
this
step
here,
verifying
on
production.
D
B
But
when
I,
when
I
try
just
this
first
like
get
request
against
the
gitlab
or
group
I
just
get
a
403.
E
B
B
A
A
That
is
so
interesting,
it's
possible
that
we're
supposed
to
do
that
and
I
just
never
knew
about
it.
So
today,
I
learned
I'll
make
sure
to
ask
my
engineering
manager
about
that.
So
I
mean
first
of
all,
I
yeah.
This
is
these
instructions.
Aren't
that
precise
I
mean
a
custom
rolls
license
is
just
something
you
get
with
ultimate,
so
custom
rolls
is
an
ultimate
feature.
A
If
you
wanted
to
check
that
in
the
future,
I
always
have
to
look
up
where
licenses
are
kept.
If
you
look
up.
C
E
B
So
I
created
a
I
created
a
group
myself,
okay,
just
initially
I
created
because
it
says
it
has
to
be
a
root
group.
So
yeah
I
create
a
group
tried.
It
got
a
403
on
there
and
then
I
I
had
actually
asked
in
slack
this.
This
same
question
of
like
any
hints
on
on
how
to
find
or
create
one
of
these
for
production,
because
I've
got
stuck
on
that
step
and
somebody
else
said:
gitlab
org
should
work,
so
I
did
switch
out
the.
B
Group
ID
here
and
I
think
I,
don't
know
anymore,
but.
A
I
know
what
the
issue
is
or
like
I'm,
pretty
sure,
I
know
what
the
issue
is,
which
is
that
you
need
to
be
a
group
owner.
So
that's
part
of
what's
missing
here.
You
need
to
not
just
have
a
license
or
an
ultimate
license.
Hey
sweetie
I
got
some
roles.
E
A
Not
just
have
a
ultimate
license,
but
you
also
need
to
be
an
owner
to
see
the
custom
roles
or
to
manage
the
custom
roles.
So
that's
what
you're
getting
a
404.
A
D
A
So
I
think
that
I
don't
know
what
the
best
way
to
like
share
that
information
in
the
future
with
people
would
be.
But
I
think
that
is
a
helpful
you
know
to
make
people
shouldn't
have
to
set
up
their
own
test
group
every
time,
they're
testing
the
feature
right
like
it's
just.
A
Should
go
to
test
it
more
easily,
so
I
can
add
you
to
that
group,
and
then
you
won't
be
stuck
on
this
step
anymore.
I.
B
A
E
E
A
Exactly
put
it
in
like
a
retro
or
something
quickly,
Malcolm,
do
you
want
your
mouth
username
or
your
mouth
block?
He
serves
her
name.
B
Oh
mellow,
please.
A
I'm
making
you
an
owner
of
this
custom
rolls
group,
so
you
should
just
thank
you.
Okay,
so,
oh
sweetie
did
you
bring
anything
you
want
to
work
on
particular
I
had
an
idea
of
a
refactor
we
could
do
together,
but
it's
just
kind
of
like
for
fun.
D
A
Cool,
so
this
is
fun,
so
I
wrote
this,
but
I
just
agree.
It's
okay!
There
was
a
lot
of
conversation
on
it
over
the
course
of
several
weeks
and
it's
basically
a
recommendation
to
in
general,
avoid
active
record
callbacks,
so
active
record
callbacks
are
really
easy
to
add
and
then
really
really
difficult
to
refactor,
and
there
are
a
lot
of
reasons
for
that.
We
have.
A
C
A
A
So
it's
unlikely
we're
ever
going
to
get
rid
of
all
of
these.
So
but
the
point
of
this
Mr
is
just
like:
hey
when
you're
adding
a
callback
like
ask
yourself
the
question:
could
this
be
somewhere
else?
Could
this
not
be
a
callback
and
so
I
think
the
consensus
was
people
are
like
okay,
we
can
do
that
and
the
risk
is
of
course,
I've
already
had
several
conversations
with
people
who
are
like
Oh.
No
I
got
an
MR,
the
Callback
and,
like
the.
A
Want
to
move
it
like
what
do
I
do.
I'm
like
it's,
okay,
like
just
accept
and
move
on,
like
we
don't
have
to
turn
every
callback
Mr
into
it's,
not
a
blocker
I
would
say
it's
more
just
like
let's
stop
and
consider
our
options,
and
so
this
already
came
up
in
an
MR.
Some
people
even
see
this
Mr
and
this
person
is
adding
a
callback.
A
Let
me
just
show
you
the
code,
it's
pretty
small!
That's
what
I
thought
it
might
be
fun
to
do
this
refactor
together,
because
it's
pretty
easy
to
understand,
what's
happening
here
and
then
to
think
about
how
you
might
refactor
it
so
they're,
adding
a
callback
to
the
band
user
model,
which
is
a
user,
has
one
band
user.
We
create
this
record
after
a
user
is
banned
and
then
at
this
is
the
after
commit
callback,
and
it
asynchronously
goes
through
and
marks
all
of
their
merge
requests.
As
author
band.
A
So
and
then
I
guess,
there's
also
an
unflag.
So
if
the
user
becomes
unbanned,
we
unmark
all
of
their
merge
requests
as
author
band
so
anyways.
There
was
a
good
conversation
over
here
with
the
author
about
why
he
put
it
in
a
callback
and
again
that's
financing
the
Callback,
but
I
thought
it
would
be
fun
to.
A
In
a
separate
Branch
like
in
a
brand
new
Branch,
see
how
difficult
it
would
be
to
refactor
this
hasn't
been
merged
yet,
but
to
like,
do
the
refactor
that's
going
to
be
necessary
to
fix
the
issue
that
you
identified
so.
E
A
The
in
the
style
guide,
Mr,
there
is
a
list
of
situations
and
callbacks
make
sense
here,
and
then
there
is
an
example
of
moving
of
like
refactoring
a
callback.
It's
a
really
simple
example.
So
you.
D
A
Into
a
service,
but
that
being
said,
you
know
it's
easy
to
write
a
style
guideline
and
sometimes
harder
to
like
do
what
it
says
so
I
think
that's
also
a
valuable
like
experience
to
be
like
okay,
here's
a
callback
like
how
would
I
actually
do
this
refactor
and
to
see
what
we
learned
in
that
process,
and
maybe
that
requires
an
update
to
the
style
guide.
A
No
in
that,
so
it
says
that
right
at
the
top
here
is
or
I
try
to
I
think
we
already
have
so
many
we're
not
trying
to
remove
all
of
them.
It's
more
just
you
know
if
you
see
an
opportunity
to
remove
one
go
for
it
and,
as
you
add
new
logic,
you
know
consider
not
adding
it
in
a
callback
if
possible,
so
we're
not
trying
to
remove
it.
So
this
exercise
is
not
like.
This
is
the
beginning
of
removing
thousands
of
callbacks.
That
would
be
really
really
rough.
A
This
is
more
just
okay.
How
do.
A
End
this
issue
and
the
issue
that
comes
up
when
you
want
to
remove
a
callback
right,
is
that
there's
some
refactoring.
That
needs
to
happen
first
right,
so
you
have
to
make
the
change
easy
and
then
you
make
easy
change,
and
so
this
we're
doing
this
a
little
bit
in
the
reverse
order
here,
but
I'm
curious
to
see
how
difficult
it
is.
So
it
all
starts
with
calling
ban
on
user.
A
A
A
A
C
E
A
Using
a
band
bang
method,
then
no
bam.
Bing
e,
okay,
okay,
I,
was
being
called
somewhere,
but
it
kind
of
is
what's
the
word,
it's
like
meta
programming.
Are
there
that's
like
Library
code,
that
kind
of
defines
the
band
bang
method.
B
And
it
usually
hooks
in
like
with
quite
often
hooks
in
with
status,
C
nums
and
creates
the
scopes
for
those
as
well
and
stuff.
A
A
A
Is
it
actually
called
after
transition
yep?
Here
we
go
after
transition,
the
active
to
band,
and
then
it
creates
a
band
user,
and
this
was
something
that
Terry
and
I.
When
we
were
discussing
this
yesterday
realized
we
were
like
what
is
create
band
user.
Create
band
user
is
just
like
a
little
thing
tactic.
Sugar
thing
that
rails
gives
you,
because
user
has
one
band
users
you
can
call
like
user.buildbanduser
or
user.createpanzer.
So
that
was
a
fine
example.
I've.
A
A
A
So
the
question
is:
how
would
we
even
start
to
think
about
refactoring
this
flow
and
making
it
so
that
we
could
call
this
whatever
method,
not
in
a
callback.
B
I
mean,
from
my
point
of
view,
often
the
motivation
to
moving
to
service
class
architecture
in
a
rails.
Application
is
so
that
you
don't
have
to
rely
on
callbacks,
because
you
get
this.
You
know
one
of
the
other
confusing
things
about
callbacks
is
like
what
order
are
those
270
callbacks
on
projects
going
to
run
it?
You
know
who
knows,
whereas
the
service
class
gives
you
a
linear
regression
through
any
task
you
want
to
run.
So
that
would
be.
My
first
place
to
go.
Is
like
okay,
where's
the
service
class
for
Banning,
a
user?
C
A
A
E
D
A
Or
if
I'm
like
clicking
around
too
fast,
sometimes
so,
the
ban
method
calls
band
service.
Dot,
execute
execute
is
not
defined
here.
It's
defined
in
band
user
service,
just
as
a
permissions
check,
it
looks
for
there's
a
state
error.
It
calls
update
user,
which
is
I
assume
defined
in
the
band
service
class
itself.
Yes,
it
just
calls
user.band,
yep,
nice,
no
Bang.
E
A
A
C
A
A
If,
after
either
my
gosh
thanks,
okay
and
I
guess
one
thing
I
don't
know
about
State
machine
is
when
we
call
user.ban.
Would
that
immediately
raise
an
error
if
it
was
a
State
change
that
wasn't
valid.
A
Yeah
I
guess
I'm
not
really
seeing
why
this
couldn't
happen
here
like
why
we
couldn't
take
the
logic
in
here,
and
there
must
be
something
I'm,
not
thinking
ever
not
aware
of.
Why
couldn't
we
just
call
this
in
here.
E
A
A
E
A
A
E
A
So
we
can
just
call
this
in
here
or
not
in
here
sorry,
NB
band
user
service
is
that
right.
A
Perform
that
I
would
assume,
there's
also
like
an
unbanned
service
yeah.
C
A
E
D
C
D
A
C
C
Yeah
update
band
state
or
something
yeah,
a
lack
of
a
better
name.
A
And
I
don't
want
to
pick
apart.
The
name
I
just
was
like
what
does
flag
mean,
I
think
it's
just
marking
the
merge
requests,
so
maybe
update
user
merge
requests.
A
Oh,
thank
you.
Oh
I,
don't
think,
and
then
this
is
the
base
service
band
user
based
service.
We
call
update
user.
So
if
update
user,
then
we
can
say,
update
user
merge
requests.
C
A
User,
oh
I,
guess
current
user
is,
is
the
person
taking
the
action
it
wouldn't
be
banning
themselves?
That
would
just
be.
It
would
be
very
kind.
E
B
I
can
point
out.
Maybe
we
might
get
some
rice
conditions
here
with
this
option?
Okay,
because
the
I
think
that
no
I'm
just
concerned
that
the
other,
the
other
callback
was
after
commit.
B
I'm
just
worried
about
what
other
callbacks
might
be
triggered
that
that
so
we're
using
after
commit
it
might
have
been
guaranteed
to
run
a
whole
load
of
callbacks
before
it
got
called
into
the
after
commit,
whereas
with
this
refactor
I'm,
not
sure
that
we
can
guarantee
that,
but
I
think
we
can
I.
Think.
Okay,
sorry.
B
C
E
B
E
B
A
A
Yeah
yeah
yeah,
yeah,
yeah,
yeah,
okay,
so
so
far
this
has
not
been
that
painful
I
would
say
which
either
means
we're
missing
something
huge
or
we
got
lucky
or
both.
D
A
When
a
user
gets
I,
think
one
of
Robert's
arguments
was
that
when
you
un
ban
a
user,
the
band
user
record
is
deleted,
but
that's
fine,
we're
not
calling
anything
on
the
unbanned
user.
We're
just
calling
a
worker
I
haven't
actually
looked
at
the
worker.
Maybe
we
should
do
that
to
make
sure
there's
nothing
in
there.
That's
depending
on
things
that
we're
not
thinking
of
isn't.
E
E
A
B
E
A
I
guess
this
is
the
future
that
my
team
owns
I'm,
not
very
familiar
with
it.
Okay,.
D
He
is
actually
mentioning
that
a
lot
of
work
for
band
user
is
being
done
only
by
a
activity
called
callbacks.
So
probably
is
scared
that
if
you
start
using
the
services,
then
we
may
not
call
the
I
don't
know
some.
Some
functionality
is
in
a
correct
order.
D
D
You
are
all
of
this
Emma.
Yes,.
C
A
E
B
E
A
A
A
C
C
B
100
down
with
the
I
think
one
of
my
pet
hates,
as
well
as
like
so
like
redefining
subject
to
the
method,
call
which,
in
my
mind,
subject,
is
always
the
object
under
test
or
it
should
be,
and
so
inside
your
it.
You
should
call
subject
dot
method
with
the
arguments,
but
we
seem
to
have
quite
a
common
pattern
where
somewhere
subjects
redefined
to
something.
B
C
A
Feel,
like
that's
my
true
dream:
I
mean
yeah
and
I
I.
Think
for
performance
reasons
we
kind
of
need,
let
it
be,
but
I
have
this
suspicion
that
sorry
I'm
still
on
the
side,
quest
I
can't
get
off
of
it.
Is
that
like
we,
because
we're
so
into
let's
we're
creating
more
data
than
we
need
for
a
lot
of
test
scenarios,
we're
not
recreating
it
with
Let
It
Be
but
then
like?
Sometimes
we
have
to
do,
let
it
be
with
reload
but
I.
Don't
know,
I
just
feel
like
I.
B
Think
one
thing
that
I've
seen
is
like
cargo
colting,
let
it
be
because
Let
It
Be
has
a
very
specific
use
case
of
like
this
is
an
expensive
object
to
build
like
project,
whereas
something
cheap.
Let
is
better
because
the
aspect
cleanup
cycle
gets
hooked
in
better,
but
people
just
let
it
be
everything,
strings,
yeah,
but
booleans.
You
know
let
it
be
just.
A
But
our
dogs
do
say,
like
always
let
it
be
I
mean.
That
is
the
documented
thing,
and
maybe
it's
an
example
like
I
agree
that
we
shouldn't
use
it
for
an
integer,
but
I.
Do
we
have
this
interesting
thing,
I
think
we're
such
a
large
team
that
works
on
the
same
code
base.
People
tend
to
like
really
respect
the
docs
too
much
it's
like
they
should
be
reading
them
and
then,
like
maybe
changing
them,
but
I
think
people
read
them
and
they're
like
okay,
like
this
is
what
I
should
do
leads.
E
D
E
A
D
Yeah,
this
looks
like
a
fallback
to
me
as
well:
I'm,
also
not
very
much
familiar
with
the
state
machines
actually,
but
I
think
this
is
a
I
feel
this
happens
once
the
transition
takes
place,
it
comes
and
calls
back
executes
the
code
block
that
we
have
mentioned
there.
I.
E
A
D
Just
on
line
number
488
in
someone.
C
B
I
think,
basically,
if
we're
kind
of
hiking
kind
of
moral
stance
on
this
change
that
like
we
don't
want
to
put
something
into
a
callback,
then
if
we
put
it
into
one
of
these
callbacks,
which
they
essentially
are
the
after
transitions,
such
as
callbacks
in
your
goldbacks.
A
Where
was
it
about
State
machine
and
she
yeah
and
the
conclusion
was
kind
of
like
yeah
State
machines
can
be
good
but
also
like,
maybe
sometimes
we
would.
We
would
want
to
use
something
else
because
they
can
be
confusing
in
a
lot
of
the
same
ways
that
callbacks
are
confusing
where
it's
like
things
have
like.
You
call
ban
and
then
like
18
things
happen
and
you
it's
hard
to
figure
out
where
or
how
but
anyways.
So
this
did
come
up
already
and
it's
interesting
that's
coming
up
in
this
conversation
already.
B
I
think
it's
one
of
those
things
where
State
machine
has
a
use
case
for
me
that
just
Banning
and
unbanning
users
is
not
necessarily
the
best
place
like
State
machine
is
not
the
state
machine
for
me
is
like
a
linear,
workflow
type.
Things
are
a
better
bit
for
that.
E
B
A
Okay,
let
me
we'll
move
this
one
next,
so
we
have
a
test
here
where
we
create
a
merge
request,
it's
not
the
author's
not
banned.
We
ban
the
user,
we
reload
it
and
we
expect
the
merge
request
author
to
show
up
as
band.
Let's
see
if
that
works.
A
It
is
okay,
I
have
an
extra
end.
E
E
B
C
A
E
C
A
That's
amazing
that
that's
also
sad
but
like.
C
A
B
D
C
A
A
C
A
E
A
E
A
C
What
does
band
user
do
in
this
case?
Because
if
it's
just
creating
that
user,
we
don't
have
a
callback
and
then.
D
Is
it
because
it's
an
asynchronous
job,
it's
not
that's!
What
I
was.
A
The
it,
what
is
true
is
this
is
for
band
service,
not
band
user
based
service.
That's
fine!
That's
fine!
This
is
Beyonce
risk,
so
we
could
put
it
I
mean
this
is
my
main
method
of
debugging
is.
E
E
E
A
B
A
Okay,
okay,
so
I'll
run
this
again
and
if
sidekick
job
is
not
executing,
then
we
probably
will
never
get
to
the
pry
and
then
I
will
be
interested
to
investigate
oh
shoot.
I
have
a
meeting.
I
have
a
coffee
chat
in
two
minutes,
but
oh
yeah
I
shouldn't
get
in
there,
so
I
think
we
have
to
call
sidekick
in
line.
Do
we
just
do
that?
Like
this
thing.
A
Okay,
the
thing
with
them,
love
them
so
much
but
autocomplete,
not
so
good.
Psychic
in
line
is
that
look
great.
A
Nice,
okay!
Well,
we
didn't
pass,
that's
fine!
We
can
figure
that
out
later,
okay.
Well,
this
was
fun.
We
didn't
complete
every
Factor
but
learn.