Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何在MVC下创建简洁的RESTful向导?_Ruby On Rails_Asp.net Mvc_Model View Controller_Rest - Fatal编程技术网

Ruby on rails 如何在MVC下创建简洁的RESTful向导?

Ruby on rails 如何在MVC下创建简洁的RESTful向导?,ruby-on-rails,asp.net-mvc,model-view-controller,rest,Ruby On Rails,Asp.net Mvc,Model View Controller,Rest,我试图在构建应用程序时尽可能地使用RESTful,但有一件事我永远不能确定,那就是如何创建向导类型的工作流,即RESTful和简洁 以多页注册流程为例 选项1:我可以为每个步骤创建一个控制器,并在用户进入该步骤(或返回该步骤)时调用new或edit。我以step1_控制器、step2_控制器等结束 选项2:我可以创建一个单控制器,并使用参数、会话变量、状态机等跟踪注册过程中的位置。所以我要注册控制器/步骤?id=1 第一个选项是严格的REST,但不是很简洁,最后是一些额外的控制器。第二个选项更简

我试图在构建应用程序时尽可能地使用RESTful,但有一件事我永远不能确定,那就是如何创建向导类型的工作流,即RESTful和简洁

以多页注册流程为例

选项1:我可以为每个步骤创建一个控制器,并在用户进入该步骤(或返回该步骤)时调用new或edit。我以step1_控制器、step2_控制器等结束

选项2:我可以创建一个单控制器,并使用参数、会话变量、状态机等跟踪注册过程中的位置。所以我要注册控制器/步骤?id=1

第一个选项是严格的REST,但不是很简洁,最后是一些额外的控制器。第二个选项更简洁,但会打断其他选项,我愿意这样做,但我不会掉以轻心

有更好的选择吗


我在RubyonRails中工作,但这个问题也适用于其他MVC实现,比如ASP.NETMVC,实际上我不太关心在一次性向导中维护REST。我认为,对于可重复的操作,REST是最重要的——您希望url基本上是可书签的,以便无论何时返回,都能获得相同的数据视图。在多步骤向导中,您的依赖关系无论如何都会破坏REST的这种透视图。我的感觉是有一个单独的控制器,具有潜在的独立操作,或者使用查询参数来指示您所处的步骤。这就是我构建激活向导(需要多个步骤)的方式。

如果您在这里应用一些DDD逻辑,这是对MVC中“M”的补充,UI的状态(注册进度)属于应用层,它可以直接与域和基础结构层对话(四层:UI、应用程序、域和基础架构)。DDD的概念让您首先“思考”如何在代码中解决解决方案。让我们一步一步地完成这个

这是进度条 您希望在此处维护的状态是注册的步骤或进度。因此,我的第一步是记录进度或“步骤”。例如,步骤1:获取用户名/通行证,步骤2:获取电子邮件。在这种情况下,我将应用逻辑将模型“移动”到下一步。很可能是使用注册服务上的NextStep()方法(RegistrationService.NextStep())

啊,但它属于应用层 我将在应用程序层创建一个名为RegistrationService的服务。我将在此处放置一个名为NextStep()的方法。但请记住,域不会在此处保留模型的状态。在这种情况下,您希望将状态集中在应用程序层。因此,在这种情况下,NextStep()将不作用于模型对象(因为它不是域责任的一部分),而是UI。因此,您需要一些东西来保持注册过程的状态

远离域模型,ViewModel怎么样? 因此,现在我们知道我们必须保留UI中某些内容的状态。MVC允许一个称为ViewModels的概念(在ASP.NET MVC中,不确定RoR如何称呼它)。ViewModel表示将由视图和/或局部视图显示的模型

ViewModel将是保存此对象状态的最佳位置当然,这意味着应用层必须保留RegistrationProgressViewModel的位置,应用层将根据NextStep操作更改其内部结构。如果它很复杂,您可能需要在应用层中创建RegistrationProgressService()并放置NextStep()在它里面把你的逻辑抽象出来

如何传递ViewModel? 最后一部分是如何跟踪该对象的状态。由于web应用程序是无状态的,因此您必须通过应用程序以外的其他方式来保持控制。在这种情况下,我将返回到以下两种方式之一:1)将ViewModel序列化到客户端,并让客户端来回传递它,或2)保留ViewModel的服务器端副本,并将某种类型的标识符来回传递给客户端

这是一个值得思考的好例子,因为我自己还没有执行过。对于#2,保存此ViewModel状态的最安全和有保障的方法是通过基础架构层将其保存到(是的,应用程序层可以直接与基础架构层对话).对我来说,这似乎是一个很大的工作,因为有些东西可能会消失,我的数据库中会有部分注册

但是,#2会将用户的私人信息(用户名、密码、电子邮件、抄送等)保存在服务器端,而不会来回传递

最后,答案! 因此,在浏览之后,我们得出了以下结论:

  • 在应用程序层中创建RegistrationProgressViewModel()
  • 在应用程序层中使用NextStep(ViewModel vm)方法创建RegistrationProgressService()
  • 执行NextStep()时,通过基础结构层将ViewModel持久化到数据库
这样,您就不必跟踪视图或UI本身上的“步骤?id=2”,因为ViewModel会在您前进的过程中得到更新和更新(验证、验证、持久化到DB)

因此,您的下一个关注点将是在UI中“向前移动”。使用一个控制器,使用步骤或命名步骤,这很容易做到

很抱歉,我正在写下面的C代码,因为这是我的语言

public class RegistrationController : Controller
{
  // http://domain.com/register
  public ActionResult Index()
  {
    return View(new RegistrationProgressViewModel);
  }

  // http://domain.com/register
  // And this posts back to itself.  Note the setting 
  // of "CurrentStep" property on the model below.
  //
  public ActionResult Index(
      RegistrationProgressViewModel model)
  {

    // The logic in NextStep() here checks the
    // business rules around the ViewModel, verifies its
    // authenticity, if valid it increases the
    // ViewModel's "CurrentStep", and finally persists
    // the viewmodel to the DB through the Infrastructure
    // layer.
    //
    RegistrationProgressService.NextStep(model);

    switch (model.CurrentStep)
    {
      case 2:
        // wire up the View for Step2 here.
        ...
        return View(model);
      case 3:
        // wire up the View for Step3 here.
        ...
        return View(model);
      case 4:
        // wire up the View for Step4 here.
        ...
        return View(model);
      default:
        // return to first page
        ...
        return View(model);
    }
  }
}
您会注意到,这将验证模型内部状态的“业务逻辑”抽象到RegistrationProcessService.NextStep()方法中

良好的锻炼。:)

最后,您的“RESTful”url是一个漂亮而干净的POST to:/register,它需要一个填写了特定属性的ViewModel。如果ViewModel无效,/register不会前进到