ThomYorkkke
ThomYorkkke

Reputation: 2131

Refactoring Rails model and controller methods into modules

I have a Rails app that is starting to get a good amount of logic in the controllers: e.g. when I create a SeatingChart I also need to create a number of Seats and Sections. So I have wrapped all this logic up into a SeatingChart.transaction block and created a method in my controller that does all the complicated logic of parsing the params received from the client, creating the various models and making sure they are associated, then I call that method in the create method of my controller.

Should I move this method into a module or is it fine to be in the controller? Or maybe should I move it into the SeatingChart model?

Another question is: some of my models have methods. They are typically small methods, as an example for my Ticket model I have a method update_status that checks to see if the reserved_until time has passed, and if so changes a few of the values for that Ticket's columns. Should methods like that be moved to a module, or are they best left for the model?

Upvotes: 0

Views: 832

Answers (4)

JMcG
JMcG

Reputation: 51

I'm not sure you should be considering using modules for your current situation. Personally I feel they are better served for reusable methods across different models/controllers.

On another note if you have a SeatingChart with a number of Seats and Sections and you are having to parse through the params and create the various models and associations manually, here are some things to checkout to make your life easier.

  1. If everything created is coming in through the params object and it's all associated, you should be able to create everything with just SeatingChart.create(params[:seating_chart]) using nested forms

  2. If your not getting all of the required data from the forms to create the associations, use active record callbacks on the models to build the required associations before saving.

Upvotes: 0

Stephen
Stephen

Reputation: 96

I agree that it is preferable to have skinny controllers for the reasons that ilan stated.

From what I can tell from your situation, I would vote that you should have that code in a module mainly because it allows you to separate concerns. Models should be dealing with a certain model. If you have code that crosses multiple models, then putting it in a module allows you keep the individual models clean.

Upvotes: 0

pauloancheta
pauloancheta

Reputation: 359

Consider using service objects. And also consider virtus gem. https://github.com/solnic/virtus

Upvotes: 1

ilan berci
ilan berci

Reputation: 3881

It's usually better to move code from the controller to the model if at all possible for a couple of reasons:

1) It's far easier to test, you can use unit testing instead of integration testing which is easier to set up and run

2) It's easier to see work. From your irb, you can just fire up the model and call the method to interact it.

3) It decouples the controller logic. Keeping the controller light helps when making your design more restfull (as you should be doing). Your controller is just their to tie your models to your views.

If the code is to be used in multiple controllers, then you are correct in assuming that you should wrap it within a module (look up service objects). Or if the controllers, are related (aka inherited from each other) then you can just pop the code in one of the base controllers.

Hope this helps

Upvotes: 3

Related Questions