为什么表单提交保持默认为特定的POST操作?

时间:2017-07-26 15:15:08

标签: ruby-on-rails ruby

想象一下典型的Rails 4.2应用程序,其中包含一个名为location的资源。在LocationsController中,我们有通常的操作。

新视图和编辑视图都使用名为_location_form.html.erb的共享部分。我想为另外两个自定义操作clone和clone_create回收相同的部分视图。克隆(GET)操作与编辑操作具有相同的代码体。 clone_create(POST)操作与create action具有相同的代码体。

最终目标是添加克隆' show.html.erb上的按钮,该按钮导致clone.html.erb具有已在共享部分上预先填充的特定位置的数据。用户相应地修改表单字段值,单击“提交”并触发clone_create操作,将该位置保存到数据库。基本上,"克隆"类似于编辑位置,然后在表单提交时创建新位置。

# new.html.erb
<h1>New Location</h1>
<%= render :partial => 'admin/shared/location_form', :locals => { :url => admin_data_provider_location_index_path } %>

# edit.html.erb
<h1>Edit Location</h1>
<%= render :partial => 'admin/shared/location_form', :locals => { :url => admin_data_provider_location_path(@location) } %>

# clone.html.erb
<h1>Clone Location</h1>
<%= render :partial => 'admin/shared/location_form', :locals => { :url => clone_create_admin_data_provider_location_index_path } %>

# _location_form.html.erb
<%= simple_form_for [:admin, @location], :url => url, :html => { :multipart => true } do |f| %>
    .................
    <%= f.submit nil, :class => 'btn' %>
<% end %>


# locations_controller.rb
class Admin::DataProvider::LocationsController < AdminController
    ................
    def new
        @location = Location.new
        ...........
    end

    def create
        # Creates a location and saves it to the database.
        ...........
        render :new
    end

    def edit
        @location = Location.find(params[:id])
        ...........
    end

    def update
        @location = Location.find(params[:id])
        # Saves edited location field values back to same location in the database.
        ...........
        render :edit
    end

    def clone
        # Same code body as edit.
    end

    def clone_create
        # Same code body as create.
    end
    ..................
end


# routes.rb
namespace :admin do
    ..........
    namespace :data_provider do
        resources :location, :controller => :locations, :exception => [:destroy] do
            get 'clone', :on => member
            post 'clone_create', :on => :collection
            .............


# rake routes | grep location
clone_admin_data_provider_location GET /admin/data_provider/location/:id/clone(.:format) admin/data_provider/locations#clone

clone_create_admin_data_provider_location_index POST /admin/data_provider/location/clone_create(.:format) admin/data_provider/locations#clone_create

edit_admin_data_provider_location GET /admin/data_provider/location/:id/edit(.:format) admin/data_provider/locations#edit

admin_data_provider_location PATCH PUT /admin/data_provider/location/:id(.:format) admin/data_provider/locations#update

new_admin_data_provider_location GET /admin/data_provider/location/new(.:format) admin/data_provider/locations#new

admin_data_provider_location_index POST /admin/data_provider/location(.:format) admin/data_provider/locations#create

克隆动作表现正常。例如,点击url / location / 123 / clone会显示填充数据的共享部分表单,就像hitting / location / 123 / edit一样。大。

提交克隆表单时出现问题。表单POST请求绝对拒绝执行clone_create操作。无论我如何修改clone.html.erb或

,表单都会每次都更新
<%= simple_form_for [:admin, @location], :url => url, :html => { :multipart => true } do |f| %>

这是一些高级Rails魔法发生在这里Rails FORCES发布到特定操作,无论开发人员代码想要什么。

1)为什么克隆表单会在我明显希望发布到clone_create时保持发布更新?

2)如何更新当前代码或我必须编写哪些附加代码以确保克隆表单发布到clone_create?

任何能更好地帮助我理解的参考链接或资源都会有所帮助。感谢。

1 个答案:

答案 0 :(得分:1)

我不知道你需要一个特定的clone_create方法。

def clone
  @location = Location.find(params[:id]).dup
  render :new
end

然后你(有效地)有一个新记录,它恰好具有与旧记录相同的值,并且可以通过标准create方法处理。

请注意,只要您显示现有记录,提交就会始终带您进行更新操作。