thoughtbot / suspenders

A Rails template with our standard defaults.
https://thoughtbot.com
MIT License
4k stars 531 forks source link

What is our preferred approach to "business logic" and transactional code? #1217

Open stevepolitodesign opened 1 month ago

stevepolitodesign commented 1 month ago

How might we standardize our approach to handling "business logic" such that we have a consistent pattern across projects?

Take this contrived example:

def update
  if @post.update(post_params)
    if @post.published?
      # Notify mailing list of new post
      # Syndicate on social media
    elsif @post.draft?
      if @post.status_previously_changed?(from: :published, to: :draft)
        # Delete comments on post
      else
        # Notify editorial staff
      end
    end
  else
  end
end

There are dozens of ways to extract this code if we wanted to. Below are just a few examples:

Rails Core

Custom

Considerations

purinkle commented 1 month ago

Is this something that we need to add to Suspenders? I prefer to have a range of opinions in our blog that we can use as a reference. We should avoid being dogmatic and leave room for creativity. I see this in the same light as performance monitoring tools or error handlers. We have a list in the Handbook, but no hard and fast rule exists.

stevepolitodesign commented 1 month ago

@purinkle

Is this something that we need to add to Suspenders? I prefer to have a range of opinions in our blog that we can use as a reference

This is a valid question. I think there could be value in having a generator for Form/Service Objects if we find that to be something most developers are reaching for. That way, we're being consistent across projects. I think the result, if any, will largely depend on our current preferences.

In the meantime, a good first step could be to explore different options in the form of a blog post per your recommendation.

I see this in the same light as performance monitoring tools or error handlers.

I think the difference here is that performance monitoring tools or error handlers are third party services, and developers may not have much influence over which ones a client purchases. This issue is concerned with code quality and conventions, which seem like a potential good fit for Suspenders.

purinkle commented 1 month ago

@stevepolitodesign, as I've sat with this for a day, I've tried to understand my feelings towards this issue. I want to make it easy to change how we write Rails applications. If we codify the approach, are we adding an unnecessary barrier to future changes? Also, who decides thoughtbot's approach? Many folks I speak to follow David Copeland's approach but use Form Objects for the service layer. Is that what everyone does? What about folks who have other opinions?

stevepolitodesign commented 1 month ago

@purinkle

If we codify the approach, are we adding an unnecessary barrier to future changes?

I think this will depend on how we codify our approach, but I think this question could be applied to everything that Suspenders does. For example, if we decide to change our decision on testing frameworks, apps generated with Suspenders before that change would use our "old" opinions on testing, and apps generated with Suspenders after that change would use our "current" opinions on testing.

Also, who decides thoughtbot's approach?

I'm hoping this issue will serve as a space for folks to voice their opinions on what our preferred approach or approaches could be.

purinkle commented 1 month ago

@stevepolitodesign, love it! I leave space for others to contribute now.

DoodlingDev commented 1 month ago

I'm in the same sort of headspace that I don't think there's something that we could add to suspenders for this particular use case. There isn't a gem or something that fills this need because that's what Ruby is for.

I have thought about making a repo or shared code snippets or something that would be little generators for patterns we have to write all the time, 3rd party API clients etc.. so we can "quality is a team sport" these project agnostic patterns as much as possible.

Does the "cookbook" idea feel like answering the question this issue is proposing?

stevepolitodesign commented 1 month ago

@DoodlingDev

I have thought about making [...] little generators for patterns we have to write all the time

This is where my head is at right now. Could (should?) Suspenders have a generator to help with this sorta thing.

bin/rails g suspenders:form_object registration

or

bin/rails g suspenders:domain registration

or even bin/rails g suspenders:concern registration is we want to lean into Concerns