Rails API ActionController :: RoutingError:没有路由匹配[POST]“/ goals”

时间:2014-04-17 01:52:17

标签: ruby-on-rails api

我正在使用Rails创建一个简单的API,而我创建目标资源的测试因RoutingError而失败 - 但我不确定原因。

我可以看到rake routesPOST /goals路线存在时。 在我的routes.rb中,我已将namespace :api设置为path: '/',因此我认为我的帖子请求应该有效。

任何人都可以帮助我指出我做错了吗?

这是我的routes.rb

Rails.application.routes.draw do

  with_options except: [:new, :edit] do |list_only|
    namespace :api, path: '/', constraints: { subdomain: 'api' }  do 
      list_only.resources :goal           
    end
  end
end

以下是我的路线:

$ rake routes

   Prefix Verb   URI Pattern          Controller#Action
api_goals GET    /goals(.:format)     api/goals#index {:subdomain=>"api"}
          POST   /goals(.:format)     api/goals#create {:subdomain=>"api"}
 api_goal GET    /goals/:id(.:format) api/goals#show {:subdomain=>"api"}
          PATCH  /goals/:id(.:format) api/goals#update {:subdomain=>"api"}
          PUT    /goals/:id(.:format) api/goals#update {:subdomain=>"api"}
          DELETE /goals/:id(.:format) api/goals#destroy {:subdomain=>"api"}

我的goal_controller.rb

  class API::GoalsController < ApplicationController
      before_action :set_goal, only: [:show, :edit, :update, :destroy]

      def index
        goals = Goal.all
        if is_complete = params[:is_complete]
          goals = goals.where(is_complete: is_complete)
        end
        render json: goals, status: 200             
      end

      def show
        goal = Goal.find(params[:id])
        render json: goal, status: 200
      end

      def create
        goal = Goal.new(goal_params)
        if goal.save
          # render nothing: true, status: 204, location: goal
          head 204, location: goal
        end
      end

      private
        # Use callbacks to share common setup or constraints between actions.
        def set_goal
          @goal = Goal.find(params[:id])
        end

        # Never trust parameters from the scary internet, only allow the white list through.
        def goal_params
          params.require(:goal).permit(:description, :motivation, :completion_date, :is_complete)
        end
    end

以下是测试:

require 'test_helper'

    class CreatingGoalsTest < ActionDispatch::IntegrationTest
      test 'creates goals' do 
        post '/goals', 
          { 
            description: "string", 
            motivation: "another string",
            completion_date: "01/01/2014",
            is_complete: true
          }.to_json,
          { 'Accept' => Mime::JSON, 'Content-Type' => Mime::JSON.to_s }

        assert_equal 201, response.status
        assert_equal Mime::JSON, response.content_type

        goal = json(response.body)
        assert_equal goal_url(goal[:id]), response.location 
      end
    end

这是错误:

$ rake test:integration
Run options: --seed 27226

# Running:

E....

Finished in 0.102621s, 48.7230 runs/s, 116.9351 assertions/s.

  1) Error:
CreatingGoalsTest#test_creates_goals:
ActionController::RoutingError: No route matches [POST] "/goals"
    test/integration/creating_goals_test.rb:5:in `block in <class:CreatingGoalsTest>'

谢谢!

1 个答案:

答案 0 :(得分:2)

如果未在测试中设置子域,因为rails期望它,您可以通过添加以下内容来覆盖提供的主机:

def setup
  host! 'api.example.com'
end

到您的测试套件。

class CreatingGoalsTest < ActionDispatch::IntegrationTest
  def setup
    host! 'api.example.com'
  end

  test 'creates goals' do 
    post '/goals', 
      { 
        description: "string", 
        motivation: "another string",
        completion_date: "01/01/2014",
        is_complete: true
      }.to_json,
      { 'Accept' => Mime::JSON, 'Content-Type' => Mime::JSON.to_s }

    assert_equal 201, response.status
    assert_equal Mime::JSON, response.content_type

    goal = json(response.body)
    assert_equal goal_url(goal[:id]), response.location 
  end
end

有关子域名和轨道测试的更多资源:Testing in Rails with Subdomains