在模块中使用Rails URL帮助程序

时间:2015-06-26 08:45:01

标签: ruby-on-rails ruby-on-rails-4 rspec versionist

我正在使用Versionist对我的API进行版本控制,所以现在我的路径文件看起来像

Rails.application.routes.draw do
  api_version(:module => "V1", :path => {:value => "v1"}) do
    resources :concepts, except: [:new, :edit]
  end
end

我的控制器位于app/controllers/v1/concepts_controller.rb

spec/controllers/v1/concepts_controller_spec.rb里面我有

  ...

  describe "POST #create" do
    context "with valid params" do
      it "creates a new Concept" do
        expect {
          post :create, {:concept => valid_attributes}, valid_session
        }.to change(Concept, :count).by(1)
      end

      ...
    end
  end

  ...

  describe "PUT #update" do
    context "with valid params" do
      let(:new_attributes) { {description: 'Sample description.'} }

      it "updates the requested concept" do
        concept = Concept.create! valid_attributes
        put :update, {:id => concept.to_param, :concept => new_attributes}, valid_session
        concept.reload
        expect(concept.description).to eq('Sample description.')
      end

      ...

PUT #update测试工作正常,但所有POST #create测试都给了我

1) V1::ConceptsController POST #create with valid params creates a new Concept
     Failure/Error: post :create, {:concept => valid_attributes}, valid_session
     NoMethodError:
       undefined method `concept_url' for #<V1::ConceptsController:0x007fd6e6d8ed38>
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_dispatch/routing/polymorphic_routes.rb:268:in `handle_model_call'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_dispatch/routing/url_for.rb:167:in `url_for'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_controller/metal/rendering.rb:95:in `_process_options'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_controller/metal/renderers.rb:43:in `block in _render_to_body_with_renderer'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_controller/metal/renderers.rb:41:in `_render_to_body_with_renderer'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_controller/metal/renderers.rb:37:in `render_to_body'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/abstract_controller/rendering.rb:25:in `render'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_controller/metal/rendering.rb:16:in `render'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_controller/metal/instrumentation.rb:44:in `block (2 levels) in render'
 # /usr/local/bundle/gems/activesupport-4.2.2/lib/active_support/core_ext/benchmark.rb:12:in `block in ms'
 # /usr/local/bundle/gems/activesupport-4.2.2/lib/active_support/core_ext/benchmark.rb:12:in `ms'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_controller/metal/instrumentation.rb:44:in `block in render'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_controller/metal/instrumentation.rb:87:in `cleanup_view_runtime'
 # /usr/local/bundle/gems/activerecord-4.2.2/lib/active_record/railties/controller_runtime.rb:25:in `cleanup_view_runtime'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_controller/metal/instrumentation.rb:43:in `render'
 # ./app/controllers/v1/concepts_controller.rb:24:in `create'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/abstract_controller/base.rb:198:in `process_action'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_controller/metal/rendering.rb:10:in `process_action'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/abstract_controller/callbacks.rb:20:in `block in process_action'
 # /usr/local/bundle/gems/activesupport-4.2.2/lib/active_support/callbacks.rb:117:in `call'
 # /usr/local/bundle/gems/activesupport-4.2.2/lib/active_support/callbacks.rb:117:in `call'
 # /usr/local/bundle/gems/activesupport-4.2.2/lib/active_support/callbacks.rb:555:in `block (2 levels) in compile'
 # /usr/local/bundle/gems/activesupport-4.2.2/lib/active_support/callbacks.rb:505:in `call'
 # /usr/local/bundle/gems/activesupport-4.2.2/lib/active_support/callbacks.rb:505:in `call'
 # /usr/local/bundle/gems/activesupport-4.2.2/lib/active_support/callbacks.rb:92:in `_run_callbacks'
 # /usr/local/bundle/gems/activesupport-4.2.2/lib/active_support/callbacks.rb:776:in `_run_process_action_callbacks'
 # /usr/local/bundle/gems/activesupport-4.2.2/lib/active_support/callbacks.rb:81:in `run_callbacks'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/abstract_controller/callbacks.rb:19:in `process_action'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_controller/metal/rescue.rb:29:in `process_action'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
 # /usr/local/bundle/gems/activesupport-4.2.2/lib/active_support/notifications.rb:164:in `block in instrument'
 # /usr/local/bundle/gems/activesupport-4.2.2/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
 # /usr/local/bundle/gems/activesupport-4.2.2/lib/active_support/notifications.rb:164:in `instrument'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_controller/metal/instrumentation.rb:30:in `process_action'
 # /usr/local/bundle/gems/activerecord-4.2.2/lib/active_record/railties/controller_runtime.rb:18:in `process_action'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/abstract_controller/base.rb:137:in `process'
 # /usr/local/bundle/gems/actionview-4.2.2/lib/action_view/rendering.rb:30:in `process'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_controller/test_case.rb:632:in `process'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_controller/test_case.rb:65:in `process'
 # /usr/local/bundle/gems/actionpack-4.2.2/lib/action_controller/test_case.rb:514:in `post'
 # ./spec/controllers/v1/concepts_controller_spec.rb:38:in `block (5 levels) in <top (required)>'
 # ./spec/controllers/v1/concepts_controller_spec.rb:37:in `block (4 levels) in <top (required)>'

我的佣金路线:

     Prefix Verb   URI Pattern                Controller#Action
v1_concepts GET    /v1/concepts(.:format)     v1/concepts#index
            POST   /v1/concepts(.:format)     v1/concepts#create
 v1_concept GET    /v1/concepts/:id(.:format) v1/concepts#show
            PATCH  /v1/concepts/:id(.:format) v1/concepts#update
            PUT    /v1/concepts/:id(.:format) v1/concepts#update
            DELETE /v1/concepts/:id(.:format) v1/concepts#destroy

如何让它使用v1_concept_url代替?为什么即使是GET请求,它甚至会调用concept_url?&#39;

编辑我的控制器:

class V1::ConceptsController < V1::BaseController
  before_action :set_concept, only: [:show, :update, :destroy]

  # GET /concepts
  # GET /concepts.json
  def index
    @concepts = Concept.all

    render json: @concepts
  end

  # GET /concepts/1
  # GET /concepts/1.json
  def show
    render json: @concept
  end

  # POST /concepts
  # POST /concepts.json
  def create
    @concept = Concept.new(concept_params)

    if @concept.save
      render json: @concept, status: :created, location: @concept
    else
      render json: @concept.errors, status: :unprocessable_entity
    end
  end

  ...

1 个答案:

答案 0 :(得分:1)

显然location标题是罪魁祸首。传入实例变量@concept会导致Rails调用concept_url帮助程序。

您可以通过自己调用帮助程序来覆盖它:

location: v1_concept_url(@concept)