如何在Ruby on Rails中编写重复的记录方法?

时间:2013-06-09 10:38:34

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

在我的Rails应用中,我有invoices_controller.rb这些操作:

def new
  @invoice = current_user.invoices.build(:project_id => params[:project_id])
  @invoice.build_item(current_user)
  @invoice.set_number(current_user)
end

def create
  @invoice = current_user.invoices.build(params[:invoice])    
  if @invoice.save
    flash[:success] = "Invoice created."
    redirect_to edit_invoice_path(@invoice)
  else
    render :new
  end
end

基本上,new方法会实例化新的invoice记录和一个关联的item记录。

现在,如果我想重复现有的invoice,我需要什么样的方法?

我是Rails的RESTful方法的忠实粉丝,所以我想知道是否应该添加一个新的方法,如

def duplicate

end

或者我是否可以使用现有的new方法,并将invoice的值传递给那里?

最佳方法是什么,该方法可能是什么样的?

3 个答案:

答案 0 :(得分:2)

当然,您可以扩展RESTful路由和控制器。

要凝聚RESTful,重要的是要准确地看,你想要什么。

即。如果您需要新发票并将现有发票用作某种模板,则它与new操作相当,动词应为GET(获取输入表单)。与基于现有发票的情况一样,它应该引用该对象。之后,您将以通常的方式create新发票。

所以你的路线:

resources :invoices do
  member do
    get 'duplicate'
  end
end

为您提供路线duplicate_invoice GET /invoices/:id/duplicate(.format) invoices#duplicate

所以在你看来你可以说

<%= link_to 'duplicate this', duplicate_invoice_path(@invoice) %>

并在您的控制器中

def duplicate
  template = Invoice.find(params[:id])
  @invoice= template.duplicate # define in Invoice.duplicate how to create a dup
  render action: 'new'
end

答案 1 :(得分:1)

如果我理解你的问题,你可以:

resources :invoices do
  collection do
    get 'duplicate'
  end
end

,你可以这样做:

def duplicate
  # @invoice = [get the invoice]
  @invoice.clone_invoice
  render 'edit' # or 'new', depends on your needs
end

clone_invoice可以是自定义方法,应该在自定义方法中调用invoice.clone

答案 2 :(得分:1)

如果您怀疑是否可以使用除REST之外的其他方法,那么您绝对可以。例如,谷歌鼓励开发人员在GoogleIO上使用他们称之为“扩展RESTful”的内容,http://www.youtube.com/watch?v=nyu5ZxGUfgs

所以使用额外的方法复制,但不要忘记“瘦控制器,胖模型”的方法来封装模型中的复制逻辑。