在我的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
的值传递给那里?
最佳方法是什么,该方法可能是什么样的?
答案 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
所以使用额外的方法复制,但不要忘记“瘦控制器,胖模型”的方法来封装模型中的复制逻辑。