【问题标题】:Rails AngularJS polymorphic best practiceRails AngularJS 多态最佳实践
【发布时间】:2014-02-20 20:28:49
【问题描述】:

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

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

  2. 每个对象(在这种情况下是每个患者)通过关联 (patient.tasks) 知道它有哪些任务,因此逻辑应该流经任何可任务对象。在 Angular 中会有一个 PatientController 会找到当前的患者,然后在 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 = '';
   });
 };
}]);

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

【问题讨论】:

    标签: ruby-on-rails angularjs design-patterns


    【解决方案1】:

    简答

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

    长答案

    选择能够降低成本并在未来轻松进行更改的解决方案

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

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

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

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

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

    Sandi Metz 在她的“Practical Object Oriented Design in Ruby”一书中对此进行了最好的解释。第 4 章很好地解释了这一点。在该章中,您处理的是 Object 的公共接口 (API),而在这个问题中,您指的是 Rails 应用程序的实际公共接口 (API),一旦你越过 Rails 应用程序的表层,你最终会处理一个 Object 接口,因为最终你可能最终会调用控制器中的一个方法,此时对象适用公共接口。

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

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

    【讨论】:

      猜你喜欢
      • 2019-02-04
      • 2016-04-04
      • 2014-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多