Rails在更新后嵌套资源重定向

时间:2017-12-08 19:18:33

标签: ruby-on-rails

美好的一天,我把头发拉出来,我已经看过类似的帖子,但没有一个让我朝着我想去的方向前进。 也就是说,我有一个非常复杂的应用程序,它严重依赖嵌套资源和名称间距,当我保存记录时它完全保存 并正确重定向。当我更新相同的记录时,URL会发生变化,但不会像我期望的那样变化。我理解从编辑到更新的流程 set_input调用拉动params [:id],我不明白为什么URL正在改变父资源以反映记录ID。

/servers/1/features/rsyslog_inputs/12/edit"
更新后

更改为以下内容

/servers/12/features/rsyslog_inputs/12/edit"

日志

Started GET "/servers/1/features/rsyslog_inputs/12/edit" for 127.0.0.1  at 2017-12-08 12:27:55 -0600
Processing by Features::RsyslogInputsController#edit as HTML
  Parameters: {"server_id"=>"1", "id"=>"12"}
  RsyslogInput Load (0.6ms)  SELECT  "rsyslog_inputs".* FROM "rsyslog_inputs" WHERE "rsyslog_inputs"."id" = $1 LIMIT $2  [["id", 12], ["LIMIT", 1]]
  Rendering features/rsyslog_inputs/edit.html.erb within layouts/application
  Rendered shared/_error_messages.html.erb (0.4ms) [cache miss]
  Rendered features/rsyslog_inputs/_form.html.erb (4.3ms) [cache miss]
  Rendered features/rsyslog_inputs/edit.html.erb within layouts/application (6.5ms)
  Rendered layouts/_shim.html.erb (0.5ms) [cache miss]
  User Load (1.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Rendered layouts/_navbar_top.html.erb (0.9ms) [cache miss]
  Rendered layouts/_navbar_side.html.erb (0.5ms) [cache miss]
  Completed 200 OK in 90ms (Views: 84.7ms | ActiveRecord: 1.7ms)

这里PATCH已经修改了servers /:id以反映rsyslog_inputs的id而没有保留它的" 1"如上所示

Started PATCH "/servers/12/features/rsyslog_inputs/12" for 127.0.0.1 at 2017-12-08 12:27:58 -0600
Processing by Features::RsyslogInputsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"dFt61NcQWXoKpmScrkngT47ZxDdhzMUcCyJ5fZKrdbaOVqKfLXMVeBUj20zKKHQ8wGe4fi2QEw98cLviyO4wQw==", "rsyslog_input"=>{"inputs_interface"=>"eth04", "inputs_ip_address"=>"1.1.1.1", "inputs_input_type"=>"tcp", "inputs_port_number"=>"22", "inputs_input_name"=>"test02", "inputs_tls"=>"0"}, "commit"=>"Save Input", "appliance_id"=>"12", "id"=>"12"}
  RsyslogInput Load (0.7ms)  SELECT  "rsyslog_inputs".* FROM "rsyslog_inputs" WHERE "rsyslog_inputs"."id" = $1 LIMIT $2  [["id", 12], ["LIMIT", 1]]
  (0.6ms)  BEGIN
  Server Load (1.0ms)  SELECT  "servers".* FROM "servers" WHERE   "servers"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  SQL (1.0ms)  UPDATE "rsyslog_inputs" SET "inputs_interface" = $1, "updated_at" = $2 WHERE "rsyslog_inputs"."id" = $3  [["inputs_interface", "eth04"], ["updated_at", "2017-12-08 18:27:58.904817"], ["id", 12]]
 (0.8ms)  COMMIT

Redirected to http://localhost:3000/servers/12/features/rsyslog_inputs
Completed 302 Found in 12ms (ActiveRecord: 4.0ms) 

控制器

class Features::RsyslogInputsController < ApplicationController
  before_action :set_input, only: [:show, :edit, :update, :destroy]

  def index
    # Let's search for all inputs associated with the corresponding appliance
    @inputs = RsyslogInput.where(server_id: params[:server_id])
  end

  def create
    @input = RsyslogInput.new(input_params)
    @input.build_server
    @input.server_id = params[:server_id]
    if @input.save
      flash[:notice] = "Input was successfully saved."
      redirect_to server_features_rsyslog_inputs_path
    else
      render('new')
    end
  end

  def destroy
    if @input.destroy
      flash[:notice] = "Input was successfully destoryed."
      redirect_to server_features_rsyslog_inputs_path
    else
      flash[:alert] = "Unable to destroy #{@input.inputs_input_name}"
    end
  end

  def update

    if @input.update(input_params)
      flash[:notice] = "Input was successfully updated"
      redirect_to server_features_rsyslog_inputs_path 
    else
      render('edit')
    end
  end

  def new
    @input = RsyslogInput.new
  end

  def edit; end

  def show ;end

  private

  def set_input
    @input = RsyslogInput.find(params[:id])
  end

  def input_params
    params.require(:rsyslog_input).permit(:inputs_interface,
                                  :inputs_input_type,
                                  :inputs_ip_address,
                                  :inputs_port_number,
                                  :inputs_input_name,
                                  :inputs_tls,
                                  :server_id)
  end


end

表格

<%= form_for ([:server, :features, @input]) do |f| %>
    <%= render 'shared/error_messages', object: f.object %>
    <br/>

    <div class="form-group  clients-form-container">
      <%= f.label :inputs_interface, 'Input interface:', class: 'col-3 col-form-label' %>
      <div class="col-3">
        <%= f.text_field :inputs_interface, class: 'form-control', placeholder: 'Enter Interface: (e.g. eth0)' %>
      </div>
      <br/>

      <%= f.label :inputs_ip_address, 'Input IP Address:', class: 'col-3 col-form-label' %>
      <div class="col-3">
        <%= f.text_field :inputs_ip_address, class: 'form-control', placeholder: 'Enter IP Address:' %>
      </div>
      <br/>

      <%= f.label :inputs_input_type, 'Input type:', class: 'col-3 col-form-label' %>
      <div class="col-3">
        <%= f.text_field :inputs_input_type, class: 'form-control', placeholder: 'TCP/UDP' %>
      </div>
      <br/>

      <%= f.label :inputs_port_number, 'Input port number:', class: 'col-3 col-form-label' %>
      <div class="col-3">
        <%= f.text_field :inputs_port_number, class: 'form-control', placeholder: 'Enter Port:' %>
      </div>
      <br/>

      <%= f.label :inputs_input_name, 'Input Name:', class: 'col-3 col-form-label' %>
      <div class="col-3">
        <%= f.text_field :inputs_input_name, class: 'form-control', placeholder: 'Enter Ruleset Name)' %>
      </div>
      <br/>
      <div class="form-inline">
        <%= f.label :inputs_tls, 'Enable TLS:', class: 'col-1 col-form-label' %>
        <div class="col-3">
          <%= f.check_box :inputs_tls, class: 'form-control check-box-alignment' %>
        </div>
      </div>
    </div>


    <%= f.submit 'Save Input', class: 'btn btn-primary btn-lg' %>
    <%= link_to 'Cancel', :back, class: 'btn btn-secondary region-btn btn-lg' %>
<% end %>
<br/>

路线

resources :servers do
    namespace :features do
      resources :rsyslog_inputs
      resources :rsyslog, only: :index
    end
  end

  server_features_rsyslog_inputs            GET     /servers/:server_id/features/rsyslog_inputs(.:format)          features/rsyslog_inputs#index
                                            POST    /servers/:server_id/features/rsyslog_inputs(.:format)          features/rsyslog_inputs#create
 new_server_features_rsyslog_input          GET     /servers/:server_id/features/rsyslog_inputs/new(.:format)      features/rsyslog_inputs#new
edit_server_features_rsyslog_input          GET     /servers/:server_id/features/rsyslog_inputs/:id/edit(.:format) features/rsyslog_inputs#edit
     server_features_rsyslog_input          GET     /servers/:server_id/features/rsyslog_inputs/:id(.:format)      features/rsyslog_inputs#show
                                            PATCH   /servers/:server_id/features/rsyslog_inputs/:id(.:format)      features/rsyslog_inputs#update
                                            PUT     /servers/:server_id/features/rsyslog_inputs/:id(.:format)      features/rsyslog_inputs#update
                                            DELETE  /servers/:server_id/features/rsyslog_inputs/:id(.:format)      features/rsyslog_inputs#destroy
     server_features_rsyslog_index          GET     /servers/:server_id/features/rsyslog_inputs(.:format)          features/rsyslog_inputs#index

2 个答案:

答案 0 :(得分:0)

看到你的表格,控制器和要求,我会建议你使用路线助手并在那里传递适当的参数

在您的表单中明确将表单url设置为 server_features_rsyslog_input(server_id: params[:server_id], id: @input.id)

并且在您的控制器中也明确传递参数

答案 1 :(得分:0)

所以这实际上是更新方法中的重定向问题。我没有指定server_id,它不允许根据服务器重定向回索引。