【问题标题】:Ruby on Rails: Using a "complete_tasks_controller" for RESTful RailsRuby on Rails:为 RESTful Rails 使用“complete_tasks_controller”
【发布时间】:2010-12-07 06:58:54
【问题描述】:

我在以 RESTful 方式完成任务时遇到了麻烦。我有一个“tasks”控制器,还有一个“complete_tasks”控制器。

我在 complete_tasks_controller 创建操作中有这个:

def create
   @task = Task.find(params[:id])
   @task.completed_at = Time.now
   @task.save
end

我试过这样称呼:

<%=link_to "Complete task", new_task_complete_task_path(@task), :method => :post %>

..但我收到错误,提到“只允许获取、放置和删除请求”。

你知道我做错了什么吗?

【问题讨论】:

    标签: ruby-on-rails ruby rest routes


    【解决方案1】:

    将其移入控制器中称为完成的操作会更有意义:

    def complete
      @task = Task.find(params[:id])
      @task.complete!
    end
    

    要使用 RESTful 路由访问此操作,您需要在 config/routes.rb 中定义一个新的成员路由,如下所示:

    map.resources :tasks, :member => { :complete => :put }
    

    :member =&gt; { :complete =&gt; :put } 添加到任何预先存在的map.resources :tasks 的末尾也可以解决问题,除非它是嵌套的,否则您应该只拥有一个map.resources :tasks 行。 routing guide 比以往任何时候都更好地解释了这一点。

    从视图中获取它:

    link_to "Complete this task", complete_task_path(@task), :method => :put
    

    然后将在您的模型中定义方法 complete!,如下所示:

    def complete!
      self.completed_at = Time.now
      save!
    end
    

    这样做的原因是它把模型逻辑放在它所属的地方:在模型中。

    【讨论】:

    • 这绝对是正确的做事方式。我正在浏览代码,并错过了使用第二个控制器的部分。
    【解决方案2】:

    每个 map.resources 语句 routes.rb 创建一个公共 RESTful 路由以用于指定资源。 REST 的吸引力在于它使用请求类型和 url 来确定要执行的操作。在与 HTTP 相关的四个动词中,每个动词都有特定的用途。

    POST => Create
    GET => Retrieve
    PUT => Update
    DELETE => Destroy
    

    您收到有关仅允许获取、放置和删除请求的错误的原因是您正在使用发布请求。本质上,您是在告诉 Rails 您要创建一个 id 为 1 的任务。但是,您不能创建已存在的项目。这就是为什么不允许发帖的原因。相反,您想使用 put,因为您正在更新现有记录。

    您可以通过更改帖子来完成此操作,以拨打您的 link_to 电话。 &lt;%=link_to "Complete task", new_task_complete_task_path(@task), :method =&gt; :put %&gt;

    阅读 routing guideresources documentation,它将帮助您了解 HTTP 请求之间的区别,并提供一些关于 Rails 如何处理这些请求的见解。

    【讨论】:

    • 太棒了!非常感谢 EmFi(和雷达)!完美运行:)
    • 伙计,这太错误了。我并不是说你使用 Rails 是错误的,这只是 Rails 尝试做 REST 的方式是错误的。执行 PUT 不应允许以这种方式进行部分更新。 PUT 是对资源的完全替换。客户端在 PUT 正文中发送的内容应该是资源的完整内容。 GPPD 确实与 CRUD 不匹配,令人遗憾的是有这么多的参考资料说它匹配。
    • Darrel,我仍在努力解决这个问题:那么哪个动词对于部分更新是正确的?或者部分更新在 RESTful 应用程序中被认为是一个坏主意?
    • @Mike PATCH - tools.ietf.org/html/draft-dusseault-http-patch-10 在这成为公认的标准之前,唯一的其他选项是 POST 到处理端点,或者使用正式的更改请求对不同的资源执行 PUT。这是一种不幸的情况,但如果无法避免部分更新,我们就需要忍受这种情况。
    • PUT is 用于部分更新。更新操作使用它并且只能编辑资源的一部分。请不要炫耀 Rails 中还没有的东西,因为这会让新手感到困惑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    • 2012-12-27
    • 2023-03-28
    • 2018-11-19
    • 1970-01-01
    • 2017-04-04
    相关资源
    最近更新 更多