“从副本复制”的REST路径

时间:2011-08-31 01:13:04

标签: ruby-on-rails-3 rest routes

对于某些型号,我希望提供允许用户根据现有记录的副本创建具有默认属性的新记录的功能。

我想知道这是什么样的正确宁静路线。

我最初的想法是它可能是new行动的参数。即借用Rails Guides examples,而不只是:

获取:/ photos / new

也允许:

获取:/ photos / new /:id

...其中:id是用作模板的记录的ID。响应将是一个新的/编辑形式,与普通的旧new相同,但值将预填充现有记录中的数据。 new控制器方法可以轻松处理参数(或缺少参数)。

替代方案似乎是创建一个新的控制器方法,例如copy,它也接受现有记录的id和上面新形式的响应。这对我来说似乎有点“不正确”,因为在用户保存新记录之前,记录实际上并未被复制(在稍微编辑之后)。

... TIA

更新:我的问题不是“我如何在rails中执行此操作?”,它是“它是RESTful吗?”

4 个答案:

答案 0 :(得分:3)

  

我的问题不是“我如何在rails中执行此操作?”,它是“它是RESTful吗?”

不,不是。就此而言,GET /photos/new也不是。{1}}。 Rails似乎在过去无可救药地陷入困境,在那里它被认为是 haute program ,用于在URI上获取GET以返回一个HTML表单,然后将x-www-form-urlencoded数据POST回相同的URI。 POST的不透明性迫使他们发明新的动词 - 如URI /photos/new,当你可能使用PUT时,或者至少使用相同媒体类型的POST。

RESTful地复制HTTP资源的最简单方法是:

GET /photos/{id}/ -> [representation of a photo resource]
...make modifications to that representation as desired...
POST /photos/ <- [modified representation]

如果您正在为浏览器实现此功能,您应该能够非常轻松地通过Ajax执行这些操作,使用位于/photos/manager.html/的HTML页面来推动与用户的交互。

答案 1 :(得分:1)

您可以尝试使用嵌套资源。我不完全确定你的应用程序的结构,但一般来说使用嵌套的照片会看起来像这样:

routes.rb

resources :photos do
  resources :photos
end

photos_controller.rb

before_filter :find_parent_photo, :only => [:new, :create]

def create
  @photo = Photo.new params[:photo]
  if @parent_photo.present?
    # fill some @photo fields from @parent_photo
  end
  @photo.save

  respond_with @photo
end

def find_parent_photo
  @parent_photo = Photo.find(params[:photo_id]) if params[:photo_id].present?
end

new.html.haml

= form_for [@parent_photo, @photo] do |f|
  -# your form code

之前当你想添加照片创作的链接时,你写了类似的东西

= link_to "new photo", [:new, :photo]

现在,如果您想根据照片@photo1

添加照片创建链接
= link_to "new photo based on other one", [:new, @photo1, :photo]

答案 2 :(得分:1)

您应该match这样的路线:

match 'photos/new/:photo_id' => 'photos#new

或者您可以在网址中传递:photo_id参数并在控制器中处理它:

'/photos/new?photo_id=17'

使用辅助方法的示例:new_photo_path(:photo_id => 17)

编辑:我不知道这是否符合REST

答案 3 :(得分:1)

它可能超过顶部,但你可以这样做:

class PhotoCopiesController < ApplicationController
  def new
    @photo = Photo.find(params[:photo_id]).dup
  end

  def create
  end
end

resources :photo_copies, :only => [:new, :create]

= link_to 'Copy', photo_copy_path(:photo_id => @photo.id)