简体   繁体   English

将Rails模型和控制器方法重构为模块

[英]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: eg when I create a SeatingChart I also need to create a number of Seats and Sections . 我有一个Rails应用程序,开始在控制器中获得大量逻辑:例如,当我创建SeatingChart我还需要创建多个SeatsSections 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. 因此,我将所有这些逻辑包装到了SeatingChart.transaction块中,并在控制器中创建了一个方法,该方法执行解析从客户端接收到的参数,创建各种模型并确保它们相互关联的所有复杂逻辑,然后我调用该方法在我控制器的create方法中。

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? 还是应该将其移动到SeatingChart模型中?

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. 它们通常是小的方法,例如,作为我的Ticket模型的示例,我有一个update_status方法,该方法检查是否已过reserved_until时间,如果是,则更改该Ticket列的一些值。 Should methods like that be moved to a module, or are they best left for the model? 应该将这样的方法移至模块,还是最好将其留给模型?

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 1)测试起来容易得多,您可以使用单元测试来代替集成测试,从而更易于设置和运行

2) It's easier to see work. 2)看工作更容易。 From your irb, you can just fire up the model and call the method to interact it. 您可以从irb中启动模型并调用方法进行交互。

3) It decouples the controller logic. 3)解耦控制器逻辑。 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 希望这可以帮助

Consider using service objects. 考虑使用服务对象。 And also consider virtus gem. 还要考虑维特斯宝石。 https://github.com/solnic/virtus https://github.com/solnic/virtus

I agree that it is preferable to have skinny controllers for the reasons that ilan stated. 我同意,由于ilan所说的原因,最好使用瘦控制器。

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. 如果您有跨多个模型的代码,则将其放在模块中可以使各个模型保持整洁。

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. 另外请注意,如果您的SeatingChart包含许多SeatsSections并且您必须解析参数并手动创建各种模型和关联,则需要进行一些检查以使您的生活更轻松。

  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 如果创建的所有内容都是通过params对象SeatingChart.create(params[:seating_chart]) ,并且都已关联,那么您应该能够仅使用SeatingChart.create(params[:seating_chart])使用嵌套表格来创建所有内容

  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. 如果没有从表单中获取所有必需的数据来创建关联,请在保存之前使用模型上的活动记录回调来构建所需的关联。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM