好的,当GitHub关闭时,代码设计问题:
我总是在rails应用程序(通常)中使用非标准RESTful操作进行分析瘫痪。
我有乔布斯,我希望能够取消(并重新激活)它们。它不像设置复选框那么简单;还有一些其他事情需要发生。所以我不能只使用现有的JobsController#update
行动。
我认为这是我的选择:
1。只需将cancel
和reactivate
添加到现有作业控制器即可。
路线将是这样的:
POST /admin/jobs/cancel/:job_id
POST /admin/jobs/reactivate/:job_id
(不是RESTful;假设这是一个坏主意)
2。使用JobCancellationsController
和create
操作创建destroy
。
重新激活作业的是destroy
- JobCancellation
资源。
我将按照以下方式使用嵌套路由:
resources :jobs, except: :show do
resource :job_cancellation, only: [:create, :destroy]
end
默认情况下会给我一些类似
的内容A)
POST /admin/jobs/:job_id/job_cancellation
DELETE /admin/jobs/:job_id/job_cancellation
我可以在不更改控制器的情况下整理路线,就像:
b)
POST /admin/jobs/:job_id/cancellation
DELETE /admin/jobs/:job_id/cancellation
虽然这看起来不太直观 - “取消”会更好cancel
。所以我可以在保持控制器相同的情况下改变路线:
c)中
POST /admin/jobs/:job_id/cancel
DELETE /admin/jobs/:job_id/cancel
第一条路线现在有意义了(虽然严格来说不是RESTful
?),但第二条路线没有......“删除工作取消”?所以你要把它改成像:
d)
POST /admin/jobs/:job_id/cancel
POST /admin/jobs/:job_id/reactivate
现在这些路线很有意义,但看起来非常接近上面的选项1),即使路线确实映射到JobCancellationsController
中的RESTful操作而不是JobsController
中的非RESTful操作。将POST /admin/jobs/:job_id/reactivate
路由映射到JobCancellationsController#destroy
操作似乎非常棒。
为了避免JobCancellationsController#destroy
的最后一次尝试,我可以改为:
3。与选项2类似,但创建了两个控制器:JobCancellationsController
只有create
操作,JobReactivationsController
带有create
只有行动。
这样做的“正确”方法是什么?或者至少,哪些是我可以迅速消除的“不正确”方式?我错过了一种完全不同的,更好的方式吗?
答案 0 :(得分:10)
在讨论了Ruby Australia的冗余渠道后,我将建议整合到下面:
答案
只需将cancel
和reactivate
添加到现有的JobsController
。
使用此代码:
resources :jobs do
post :cancel, on: :member
post :reactivate, on: :member
end
创建路线,如:
POST /admin/jobs/:job_id/cancel
POST /admin/jobs/:job_id/reactivate
这很简单直观,即使它不是严格的REST。
(另一种建议的方法是修补现有的update
方法,其状态为已取消;但我想在cancels
与常规{{updates
的更新方法中需要条件。 1}})
讨论中提出的其他有用的观点
在您被出售时,资源不是资源是一个常见的陷阱" REST是最好的!" (即,Jobs
是一种资源,但JobCancellations
并非如此,所以不要试图将它们作为资源。
如果您不需要删除作业,则可以使用destroy
操作取消作业,而不是cancel
操作。
IMO完整REST仅在您不可能遇到的某些情况下有用,除非您是大公司。
制作有意义的API。 Rails只提供了轻松完成CRUD的方法。这与宁静有关,但并不是全部。
REST(或HATEOS)方法是让/jobs/1234.json
包含cancelLink: {url: "url", method: "POST", rel: "link to the docs"}
属性
当我们构建API时,我们有一个非官方的规则,即如果我们不确定要做什么,我们只需复制github所做的事情,因为我们喜欢他们的API。
fwiw,我已经使用了一堆"休息" API根据休息设计得很好,但作为开发人员使用起来很糟糕。更重要的是你A)覆盖原语和B)使它比你遵守REST(或HATEOS,或者你今天所关注的任何东西)一样友好。
以上所有内容基本上都指向我总是试图告诉自己的建议:"最重要的是代码简单易懂。设计模式只有在它们帮助您实现该目标的范围内才有用。如果设计模式没有实现这一目标,那么您可能会错误地使用它,或将其应用于不正确的情况,或者过于严格地遵循它#34;。
答案 1 :(得分:2)
在这个特定的情况下,为什么不只是
# 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
有很多可能会遇到一般的“你没有做正确的REST”辩论,我认为我并不真正关心这一点。这个特殊情况看起来有一个不错的解决方案。
FWIW,你真的需要重新启动相同的工作吗?要求取消后创建新作业可能会更加清晰。也许提供一些克隆现有工作的机制。