【问题标题】:routing to nested rails route路由到嵌套的 rails 路由
【发布时间】:2017-07-19 14:30:12
【问题描述】:

我正在尝试创建一个 rspec 以路由到嵌套资源,但我不断收到 No route matches 错误。

1) V1::DevicesController scan submitted to #create
     Failure/Error: post "/v1/devices/#{device.serial_number}/scans.json", params: { data: scan }

     ActionController::UrlGenerationError:
       No route matches {:action=>"/v1/devices/7929e287466c493ba03947c189cadc81/scans.json", :controller=>"v1/devices", :data=>#<Rack::Test::UploadedFile:0x00556f7c423808 @content_type="application/gzip", @original_filename="sample_test.gz", @tempfile=#<Tempfile:/tmp/sample_test.gz20170719-65-sdfczl>>}

我的规范现在很简单:

需要“rails_helper”

RSpec.describe V1::DevicesController, type: :controller do
  it "scan submitted to #create" do
    company = Company.create(name: "Test Company", domain: "testcompany.com")
    device = Device.create(name: "Test Device", company_id: company.id)
    scan = fixture_file_upload( "#{Rails.root}/spec/assets/sample_test.gz", 'application/gzip')
    post "/v1/devices/#{device.serial_number}/scans.json", params: { data: scan }
    expect(response).to be_successful
  end    
end

我的控制器也比较基础:

class V1::ScansController < ApplicationController
  skip_before_action :authenticate_user_from_token!, only: [:create]
  skip_before_action :authenticate_user!, only: [:create]
  skip_before_filter :verify_authenticity_token, :if => Proc.new { |c| c.request.format == 'application/json' }, only: [:create]

  def create
    @scan = Scan.new(scan_params)

    respond_to do |format|
      if @scan.save
        # GenerateReport.perform_async(@scan.id)
        format.json { render json: @scan, status: :created }
      else
        format.json { render json: @scan.errors, status: :unprocessable_entity }
      end
    end

  end


  private

  def set_device
    @device = Device.find_by!(serial_number: params[:device_serial_number])
  end

  def scan_params
    params.require(:scan).permit(:device_serial_number, :data)
  end

end

我的路线文件有:

api_version(:module => "V1", :path => {:value => "v1"}) do
  resources :devices, only: [:show, :update], param: :serial_number do
    resources :scans, only: [:create]
  end
end

产生以下路线:

v1_device_scans POST   /v1/devices/:device_serial_number/scans(.:format) v1/scans#create

那么,显然我的路线就在那里......我错过了什么?

【问题讨论】:

  • 问题来自post "/v1/devices/#{device.serial_number}/scans.json",,你需要给它一个映射的路线符号。
  • 什么意思?类似post :create, params: { device_serial_number: device.serial_number }
  • 是的,通常我们把action method name作为一个符号放在那里,试试看。
  • 几乎相同:No route matches {:action=&gt;"create", :controller=&gt;"v1/devices", :data=&gt;#&lt;Rack::Test::UploadedFile:0x0055e05d093380 @content_type="application/gzip", @original_filename="sample_test.gz", @tempfile=#&lt;Tempfile:/tmp/sample_test.gz20170719-109-5v46iw&gt;&gt;, :device_serial_number=&gt;"da512d2b15de4bd887161d6cb83e79b2"}

标签: ruby-on-rails ruby rspec


【解决方案1】:

结合使用 Mathew 和 Gerry 的想法,我能够通过以下方式解决 no route 问题:

post :create, params: { device_serial_number: device.serial_number, scan: { data: scan } }

由于我的控制器有这个方法,我最终需要在 params 哈希中嵌套附加属性:

  def scan_params
    params.require(:scan).permit(:device_serial_number, :data)
  end

【讨论】:

  • 太棒了!我认为我们混合了两种参数,我们需要这个 device_serial_number 来路由到正确的操作,然后我们需要 data 来执行操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-22
  • 2020-07-18
  • 1970-01-01
  • 2011-09-07
相关资源
最近更新 更多