All threads / Using Ruby Service Objects To Refactor Your Rails Code Discussion
Ask A Question


You’re not receiving notifications from this thread.

Using Ruby Service Objects To Refactor Your Rails Code Discussion

Very nice video Chris! I really like the idea of breaking things out into POROs. I think the next refactoring I would do to this app is making a Subscription class to house the logic for adding and updating the mailchimp list. Since multiple parts of your app could end up needing to add someone to mailchimp. Also feels like its violating SRP there.

Kohl Kohlbrenner ·

Can you use active record queries in PORO's i.e. Lead.find in UpdateLead class

Yep! All your classes are available inside your POROs like you would expect. The things you won't have access to are things like "params" that come from inheriting ApplicationController. You'll have to pass those in.

Kohl Kohlbrenner ·

Arent you calling lead_params twice? First, when you call and then when you call @lead = lead_params inside the save method on the CreateLead class ? Couldn't you just do @lead = because we pass lead_params into the @params variable when we instantiate the instance of the PORO class. Or, b/c params is just an attribute on the CreateLead Class, we can't do that.

Good catch! That should actually reference @params in the PORO because it doesn't have access to lead_params in there unless you move that code too.

Kohl Kohlbrenner ·

P.S. on the index page, please keep the runtime length for each screencast next to it's release date. Every now and then I see you take it down! Is that a design decision?

I don't think I've touched that for a bit. If you see it broken, send me a screenshot and I'll make sure to correct it. They should definitely be on the index page.

Hey Chris! I've been trying to "dumb down" service objects with a basic association between blogs and posts. I want to organize my model folder exactly how you have all of your lead related objects under the model / folder but I'm stumped. Can you point me in the right direction?

Hey James! You can actually generate these types of nested models with Rails:

rails g model Blog::Post title

That will create the Post model nested inside the blog folder. The table name will be "blog_posts" because database tables don't have nesting. They just scope it by prepending "blog_" at the beginning in the database table. I agree with the StackOverflow poster in that you shouldn't try to override the table name to be safe. You can still scope it in your code and so long as you don't also create a "BlogPost" model, you will be fine.

Ok, I guess that works! So does this guys' solution below also require prepending the table like you said?

Yeah in the database I think you would have both "users" and "something_users" tables.

Very good video Chris. One question, do we have to put this:
config.autoload_paths += Dir[Rails.root.join('app', 'models', '{*/}')]
in order to load the folder Leads inside the model?

I've tried without and I'm getting uninitialized constant ReviewsController::CreateReview . I have a reviews folder inside the models with createReview.

The class has to match the filename exactly. If you have app/models/reviews/create_review.rb you need to have a class Reviews::CreateReview defined in it. It must match the folder and filename for autoloading to work automatically. Folders equate to namespaces, and underscored filenames are converted to cased words.

What is the advantage of using that way ( autoloading ) over writing something like this config.autoload_paths += Dir[Rails.root.join('app', 'models', '{*/}')] ?

Mainly it's good convention to keep one class per file, and have the class inside the file named exactly the same.

Rails already does autoloads that path, it's just that it requires the class inside to match the folder+filename. So since it already does that, you might as well just follow the convention.

If you would like to find out more on Service Objects, check out this blog post:
Hope it helps!

Yes, this is easy to apply

this is great, but it misses a very important thing which is: a proper way for error handling while performing these operations(create/update etc).

Join the discussion

Want to stay up-to-date with Ruby on Rails?

Join 70,337+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    logo Created with Sketch.

    Screencast tutorials to help you learn Ruby on Rails, Javascript, Hotwire, Turbo, Stimulus.js, PostgreSQL, MySQL, Ubuntu, and more. Icons by Icons8

    © 2023 GoRails, LLC. All rights reserved.