ruby-on-rails - Rails AngularJS 多态最佳实践

标签 ruby-on-rails angularjs design-patterns

我有一个 Rails 多态模型“任务”。将有许多具有“任务”的不同模型。现在我有一个模型“患者”,对于每个患者,我需要提取分配给他们的任务,将它们放在每个患者索引页面上,然后使用 angular.js 处理该页面内任务的粗略操作。我一直在进行的内心斗争由此而来。我可以看到两种截然不同的方法,但我不确定哪种方法被认为是最佳设计实践:

  1. 将有许多具有任务的 Rails 对象,因此任务应将所有逻辑保留给自己并破译哪个对象要求执行任务。将有一个 Angular 的 TasksController,它将通过您所在的页面知道您正在处理的“可任务”对象是什么。然后它将查询 tasks_controller 以提取与该任务对象相关的所有任务。对于每个 crud 操作,任务对象和资源将处理数据。

  2. 每个对象(在本例中为每个患者)通过关联 (patient.tasks) 知道它有什么任务,因此无论可任务对象是什么,逻辑都应该流过。在angular中会有一个PatientsController,它会找到当前的患者,然后在rails中查询patients_controller,并返回分配给该患者的相关任务。对于每个 crud 操作,患者对象和资源将处理数据。

现在我选择了选项 1。这是我的 TasksController.js:

BC.controller('TasksController', ['$scope', 'TaskResource', function($scope, TaskResource){
  $scope.init = function(taskableId, taskableType, currentUserId) {
    $scope.task = {};
    $scope.task.taskableId = taskableId;
    $scope.task.taskableType = taskableType;
    $scope.task.creatorId = currentUserId;

    TaskResource.query({taskable_id: $scope.task.taskableId, taskable_type: $scope.task.taskableType}).then(function(result){
      $scope.tasks = result.reverse();
    });
  };

 $scope.taskCreate = function($event, task){
   $event.preventDefault();
   new TaskResource({text: task.text, taskableType: task.taskableType, taskableId: task.taskableId, creatorId: task.creatorId})
   .create().then(function(result){
     $scope.tasks.unshift(result);
     $scope.task.text = '';
   });
 };
}]);

我有一个初始化函数,我在其中传入我所在的任何页面的 taskable_id 和 taskable_type,以便从 tasks_controller 和 Task 模型查询正确的任务。这目前正在工作,但我开始看到一些可能的设计问题,并且不禁觉得这可能是一个糟糕的设计实践。对此的任何帮助/想法将不胜感激。谢谢。

最佳答案

简答

简短的回答,第一个选项符合“标准做法”,是更好的选择。最佳实践始于如何您实现此标准实践 - 或前端 - 后端应用程序中出现的标准需求

长答案

选择等同于成本更低并使 future 更改变得容易的解决方案

一旦您确定了标准实践——如何最好地安排 Angular <=> Rails 的通信,就会开始寻求最佳实践,因为它应该如何流动。有很多方法可以采取。 Restangular , Angular 低水平 $http , Angulars 高级 ngResource ,或 Rails 特定方法 - angularjs-rails-resource .这些都有效,还有更多。

但是您正在使用其中之一,这不是您的问题。这里要问的微妙问题不是这些人应该用什么方式说话,而是他们应该用什么方式说话。这种情况下的最佳实践实际上是由一组指南而不是规则决定的。这些准则规定,最好的解决方案可能在某种程度上对您自己的应用程序来说是独一无二的,而这一切都是关于利用您做出的每个选择的成本。

问题出在应用的早期阶段,我们永远不知道实际成本。正如 Sandi Metz 所言,“你知道的永远不会比现在少”。因此,我建议在开始阶段,无论何时您面临此类决策,都应选择最能利用您的 API 的决策。与其在 Angularjs 中做任何形式的弄清楚你想要什么,不如将数据传递给 Rails API 并让它弄清楚。在这个级别,您将想要使用痛苦驱动的开发——聆听您的应用程序的痛苦。当事情变得艰难时,退后一步,看看是什么导致了痛苦。听听痛苦。它会在出现问题时告诉您。

使用 SOLID 原则构建您的公共(public)界面

这个概念源于 SOLID面向对象的设计。它的要点是制作易于更改的应用程序的指南,以 Angular 所说的方式运行 *“Hello Rails API,我知道你有我想要的,我相信你会把它还给我”而不是说 *“你好 Rails,我知道你有我想要的,我知道你需要如何得到它”这只比最坏的情况好一点,“你好,Rails 先生。我知道你有我想要的,我知道什么我想要,而且我知道如何得到它。”

Sandi Metz 在她的书“Ruby 中的实用面向对象设计”中对此进行了最好的解释。第 4 章解释得很好。在该章中,您处理的是 Object 的公共(public)接口(interface) (API),而在这个问题中,您指的是 Rails 应用程序的实际公共(public)接口(interface) (API),一旦你越过 Rails 应用程序的表面层,你最终会处理一个 Object 接口(interface),因为最后你可能最终会调用你的 Controller 中的一个方法,此时对象 公共(public)接口(interface)适用。

代码胜于 Eloquent ,如果其中一些没有意义,请发布更多代码,我们可以尝试用比语言更容易理解的代码来解释这一点:)

编辑:我计划再次解决这个问题,看看我能否以更易于理解的方式重组它

关于ruby-on-rails - Rails AngularJS 多态最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21424259/

相关文章:

javascript - 使用纯 javascript 拖放并再次拖动

oop - 确保在方法 B 之前调用方法 A 的设计模式

ruby-on-rails - 如何在 Rails 中将非持久数据添加到模型中?

java - 带有 Java 库的 JRuby 应用程序需要访问数据库

ruby-on-rails - 使用 Searchkick 或 Rails + ElasticSearch 在地理多边形内进行记录

javascript - 如果 angularjs 中的值为空,则删除 href 属性

javascript - 将返回值传递给另一个函数,javascript

javascript - 使用 javascript 动态渲染消息 - Rails

ruby-on-rails - rails 按 created_at 的日期分组记录

javascript - Angular 形式 ng 所需的表达式被调用多次