Ruby on rails Rails中的非RESTful操作

Ruby on rails Rails中的非RESTful操作,ruby-on-rails,rest,Ruby On Rails,Rest,好的,当GitHub关闭时,一个代码设计问题: 我总是在rails应用程序中(通常)使用非标准的RESTful操作而导致分析瘫痪 我有工作,我希望能够取消(并重新激活)它们。它不像设置复选框那么简单;还有一些事情需要做,所以我不能只使用现有的JobsController#update操作 在我看来,以下是我的选择: 1.只需将cancel和重新激活添加到现有作业控制器中即可。 路线大致如下: POST /admin/jobs/cancel/:job_id POST /admin/jobs/rea

好的,当GitHub关闭时,一个代码设计问题:
我总是在rails应用程序中(通常)使用非标准的RESTful操作而导致分析瘫痪

我有工作,我希望能够取消(并重新激活)它们。它不像设置复选框那么简单;还有一些事情需要做,所以我不能只使用现有的
JobsController#update
操作

在我看来,以下是我的选择:

1.只需将
cancel
重新激活
添加到现有作业控制器中即可。 路线大致如下:

POST /admin/jobs/cancel/:job_id
POST /admin/jobs/reactivate/:job_id
(不安静;假设这是个坏主意)

2.使用
创建
销毁
操作创建一个
作业取消控制器
。 重新激活作业就是销毁
作业取消
资源

我将使用嵌套路由,如下所示:

resources :jobs, except: :show do
  resource :job_cancellation, only: [:create, :destroy]
end
默认情况下会给我类似的东西

(a)

我可以在不改变控制器的情况下,自行整理路线,如下所示:

(b)

虽然这看起来不是很直观-“取消”会更好,因为
cancel
。因此,我可以在保持控制器不变的情况下更改路由:

(c)

第一条路线现在是有意义的(虽然严格来说它不是RESTful的,但是第二条路线不是。。。“删除作业取消”?因此,您可以将其更改为:

(d)

现在,这些路由是有意义的,但看起来似乎与上面的选项1)非常接近,即使路由确实映射到
jobscancellationscocontroller
中的RESTful操作,而不是
JobsController
中的非RESTful操作。将
POST/admin/jobs/:job\u id/reservate
路由映射到
job cancellations控制器#destroy
操作似乎非常奇怪

为了避免
作业取消控制器#destroy
的最后一个问题,我可以改为:

3.与选项2类似,但创建两个控制器:
JobCancellationsController
仅使用
create
操作,以及
JobReactivationController
仅使用
create
操作


“正确”的方法是什么?或者至少,我可以快速消除哪些“不正确”的方法?有没有一种完全不同的、更好的方式让我错过了呢?

在这种特殊情况下,为什么不干脆

# Cancel a job (handled by your cancellations controller)
DELETE /admin/jobs/:job_id

# Likewise, reactivate a job if so instructed by the request body
PATCH /admin/jobs/:job_id
有很多可能会陷入“你没有好好休息”的一般性辩论,我认为我真的不想卷入其中;这个特殊的案例看起来有一个不错的解决方案


FWIW,你真的需要允许重新激活同一个作业吗?一旦取消,要求创建一个新作业可能更为明确。也许可以提供一些机制来克隆现有作业。

在讨论了Ruby Australia slack频道后,我将建议整合到以下内容中:

答案

只需将
取消
重新激活
添加到现有的
作业控制器

使用此代码:

resources :jobs do
  post :cancel, on: :member
  post :reactivate, on: :member
end
要创建路线,请执行以下操作:

POST /admin/jobs/:job_id/cancel
POST /admin/jobs/:job_id/reactivate
这是简单和直观的,即使它不是严格的RESTful

(另一个建议的方法是修补现有的
update
方法,状态为cancelled;不过我想,对于
cancels
与常规
更新
,更新方法中需要一个条件)

讨论中提出的其他有用的观点

  • 当你被推销“休息是最好的!”(即,
    Jobs
    是一种资源,但是
    jobscancellations
    不是真正的资源,所以不要试图让它们成为一种资源)时,为非资源的东西提供资源是一个常见的陷阱

  • 如果不需要删除作业,可以使用
    destroy
    操作来取消作业,而不是
    cancel
    操作

  • 在我看来,完全休息只在某些情况下有用,除非你在一家大公司,否则你不太可能遇到这种情况

  • 制作一个有意义的API。Rails只是提供了简单地处理积垢的方法。这与restful有关,但不是全部

  • 剩下的(或HATEOS)方法是使用
    /jobs/1234.json
    包括
    cancelLink:{url:“url”,method:“POST”,rel:“link to the docs”}
    属性

  • 当我们构建API时,我们有一个非官方的规则,如果我们不确定要做什么,我们只会复制github所做的,因为我们喜欢他们的API

  • fwiw,我使用了一堆“rest”API,它们是根据rest精心设计的,但作为开发人员使用起来很糟糕。更重要的是,您A)覆盖原语,B)使其易于使用,而不是始终遵守REST(或HATEOS,或您今天关注的任何内容)


以上这些基本上都是我一直试图告诉自己的建议:“最重要的是代码简单易懂。设计模式只有在帮助您实现该目标时才有用。如果一个设计模式没有达到这个目标,那么很可能是您错误地使用了它,或者将它应用于错误的情况,或者过于严格地遵循它“

谢谢。我在Ruby Australia slack频道上对此进行了很好的讨论。这个建议与你的建议并不遥远,但有一些额外的信息值得了解。我很快会把它整理成一个答案。顺便说一句,是的,肯定需要重新激活。有几件事。(1) 取消是个错误的词;叫它去激活。(2) 作业取消不是资源,而是任务/操作。(3) 我认为资源是“活动”标志,嵌套在作业下,设置为真或假。是的,这是有道理的。那么你会有一个JobActiveFlagsController吗?我不知道你是否可以假设它像一个标志一样简单;取消作业可能会产生一些与cre语义更为匹配的值得注意的资源
POST /admin/jobs/:job_id/cancel
POST /admin/jobs/:job_id/reactivate
# Cancel a job (handled by your cancellations controller)
DELETE /admin/jobs/:job_id

# Likewise, reactivate a job if so instructed by the request body
PATCH /admin/jobs/:job_id
resources :jobs do
  post :cancel, on: :member
  post :reactivate, on: :member
end
POST /admin/jobs/:job_id/cancel
POST /admin/jobs/:job_id/reactivate