我正在尝试在我的Rails应用程序中测试ArticlesController。所有不接受参数的路线都在经过。但是所有期望id param的路由都失败了。
1) ArticlesController should find article by id
Failure/Error: get :info, id: @article[:id]
ActionController::UrlGenerationError:
No route matches {:action=>"info", :controller=>"articles", :id=>"60"}
# ./spec/controllers/articles_controller_spec.rb:26:in `block (2 levels) in <top (required)>'
2) ArticlesController should export folder
Failure/Error: get :export_folder, id: @article[:id]
ActionController::UrlGenerationError:
No route matches {:action=>"export_folder", :controller=>"articles", :id=>"60"}
# ./spec/controllers/articles_controller_spec.rb:56:in `block (2 levels) in <top (required)>'
3) ArticlesController should export an article by id
Failure/Error: get :export, id: @article[:id]
ActionController::UrlGenerationError:
No route matches {:action=>"export", :controller=>"articles", :id=>"60"}
# ./spec/controllers/articles_controller_spec.rb:50:in `block (2 levels) in <top (required)>'
get '/articles/list' => 'articles#list', defaults: { format: :html }
get '/articles/trendlist' => 'articles#trendlist', defaults: { format: :html }
get '/articles/show/:id' => 'articles#show', defaults: { format: :html }, as: :show_article
get '/articles/index'
get '/articles/info/:id' => 'articles#info', as: :article_info
get '/articles/export/:id' => 'articles#export', as: :export_article
get '/articles/view/:id' => 'articles#view'
get '/articles/favorite/:id' => 'articles#favorite'
get '/articles/trending' => 'articles#trending', defaults: { format: :json }
get '/articles/deleted' => 'articles#deleted', defaults: { format: :json }
get '/articles/csv/:id' => 'articles#csv'
get '/articles/export_folder/:id' => 'articles#export_folder', as: :export_folder
require 'spec_helper'
describe ArticlesController do
before(:all) do
Article.destroy_all
Comfy::Cms::Layout.destroy_all
Comfy::Cms::Site.destroy_all
site = FactoryGirl.create(:cms_site)
layout = FactoryGirl.create(:cms_layout, site_id: site[:id])
@article = FactoryGirl.create(:cms_page, layout_id: layout[:id], site_id: site[:id])
end
it 'should index articles' do
get :index
expect(response.response_code).to eq(200)
expect(response.headers).to include( 'Content-Type' => 'application/json; charset=utf-8')
end
its 'should list articles' do
get :list
expect(response.response_code).to eq(200)
expect(response.headers).to include( 'Content-Type' => 'text/html; charset=utf-8')
end
it 'should find article by id' do
get :info, id: @article[:id]
expect(response.response_code).to eq(200)
expect(response.headers).to include( 'Content-Type' => 'application/json; charset=utf-8')
end
it 'should list deleted articles' do
get :deleted
expect(response.response_code).to eq(200)
expect(response.headers).to include( 'Content-Type' => 'application/json; charset=utf-8')
end
it 'should list trending articles' do
get :trending
expect(response.response_code).to eq(200)
expect(response.headers).to include( 'Content-Type' => 'application/json; charset=utf-8')
end
it 'should update trending articles' do
get :trendlist
expect(response.response_code).to eq(200)
expect(response.headers).to include( 'Content-Type' => 'text/html; charset=utf-8')
end
it 'should export an article by id' do
get :export, id: @article[:id]
expect(response.response_code).to eq(200)
expect(response.headers).to include( 'Content-Type' => 'text/csv; charset=utf-8')
end
it 'should export folder' do
get :export_folder, id: @article[:id]
response.response_code.should eq(200)
expect(response.headers).to include( 'Content-Type' => 'text/html; charset=utf-8')
end
end
Prefix Verb URI Pattern Controller#Action
tags GET /tags(.:format) tags#index
articles_list GET /articles/list(.:format) articles#list
articles_trendlist GET /articles/trendlist(.:format) articles#trendlist
articles GET /articles/show/:id(.:format) articles/articles#show
articles_index GET /articles/index(.:format) articles#index
GET /articles/info/:id(.:format) articles/articles#info
GET /articles/export/:id(.:format) articles/articles#export
GET /articles/view/:id(.:format) articles/articles#view
GET /articles/favorite/:id(.:format) articles/articles#favorite
articles_trending GET /articles/trending(.:format) articles#trending
articles_deleted GET /articles/deleted(.:format) articles#deleted
GET /articles/csv/:id(.:format) articles/articles#csv
GET /articles/export_folder/:id(.:format) articles/articles#export_folder
class ArticlesController < ApplicationController
include ArticlesHelper
before_action :set_default_response_format, except: [:pdf, :show, :list, :trendlist, :export_folder]
def index
@articles = SearchArticlesCommand.new(params).execute
end
def deleted
@dlist = Article.deleted.map(&:article_id)
render :ids, status: :ok
end
def info
id = params[:id].to_i
@article = Article.published.find_by(id: id)
end
def list
@articles = Article.folder
render 'articles/list'
end
def favorite
...
render json: { result: true, is_liked: "#{is_liked}" }
end
def view
...
render json: { result: true }
end
def trending
load_trending_articles
end
def trendlist
load_trending_articles
render 'articles/trendlist'
end
def export
id = params[:id].to_i
@article = Article.published.find_by(id: id)
render pdf: @article.label.gsub(/\s/, '_'),
template: 'articles/export.pdf.erb',
dispostion: 'attachment',
locals: { paragraphs: @article.paragraphs, images: @article.images }
答案 0 :(得分:2)
这不是namespace
的用途。您可以在其上阅读更多内容here。请改用resources
并为member
id
resources :articles, only: [] do
collection do
get :list
get :trendlist
get :trending
get :deleted
end
member do
get :info
get :export
get :view
get :favorite
get :csv
get :export_folder
end
end
get 'articles/index', to: 'articles#index'
get 'articles/show/:id', to: 'articles#show'
答案 1 :(得分:2)
如果查看rake routes
的输出,您可以看到Rails正在寻找articles/articles#show
等。namespace
用于创建位于名称空间(duh)中的路由,例如{ {1}}根据/admin/tools
。
您可以使用Admin::ToolsController
添加网址前缀但不添加命名空间或scope
:
resources
我还会质疑为什么你真的需要超出标准CRUD集的那么多路由。 特别是在视图和节目以及列表和索引等语义极其类似的路径。
我会在较小的路由集周围使用查询参数,因为它会减少所有级别的重复数量。
resources :articles, only: [:show, :index] do
member do
get 'info'
get 'export' # Use /articles/1.format instead.
get 'view' # Do you need this? Code smell!
get 'favorite' # should be post - GET should never create or alter a resource.
get 'csv' # remove - use /articles/1.csv instead
get 'show' # /articles/show/3
end
collection do
get 'trending'
get 'deleted'
get 'trendlist'
get 'list' # Do you need this? Code smell!
get 'index' # /articles/index
end
end
Rails还有内置的CSV mime类型,您可以这样做:
/articles?filter=deleted => index
/articles?filter=trending
/articles/5.csv
使用class ProductsController < ApplicationController
def show
@article = Article.order(:name)
respond_to do |format|
format.html
format.csv { render text: @article.to_csv }
end
end
end
vs @article[:id]
确实有效,但由于rails必须通过@article.id
方法才能找到getter方法,因此它非常简单且速度稍慢。在这种情况下,这并不是一件大事,但在处理大量物体时并不是很好。