0

我正在尝试在 Controllers 文件夹中为我的 rails 应用程序创建一个 api 我创建了以下文件夹结构

控制器 > api > v1

我的路线看起来像这样需要'api_constraints'

MyApp::Application.routes.draw do
  devise_for :users

  resources :users

  ......
   other resources and matching for the standard application
  ......

  # Api definition
  namespace :api, defaults: { format: :json },constraints: { subdomain: 'api' }, path: '/'  do
    scope module: :v1,constraints: ApiConstraints.new(version: 1, default: true) do
      resources :sessions, :only => [:create]
      resources :users, :only => [:show]
    end
  end
end

我在会话和用户控制器中都遇到了同样的错误。我将只发布用户控制器,因为它更短

class Api::V1::UsersController < ApiController
  respond_to :json

  def show
    respond_with User.find(params[:id])
  end
end

然后我的测试是

require 'spec_helper'

describe Api::V1::UsersController do

  describe "GET #show" do
    before(:each) do
      @user = FactoryGirl.create :user
      get :show, id: @user.id, format: :json
    end

    it "returns the information about a reporter on a hash" do
      user_response = JSON.parse(response.body, symbolize_names: true)
      expect(user_response[:email]).to eql @user.email
    end

    it { should respond_with 200 }
  end
end

测试的输出是

4) Api::V1::UsersController GET #show Failure/Error: get :show, id: @user.id, format: :json ArgumentError: 错误数量的参数(0 代表 1)

两个问题是 1)由于某种原因,id 没有被发送到 api 操作 2)我不确定如何访问 api。我以为应该是 api.localhost:3000/users/1

提前感谢您的帮助

更新 这是 rake 路由的输出

api_sessions POST   /sessions(.:format)                         api/v1/sessions#create {:format=>:json, :subdomain=>"api"}

api_user GET    /users/:id(.:format)                        api/v1/users#show {:format=>:json, :subdomain=>"api"}

更新 2创建我的用户时, 这看起来像是 参数数量错误(0 表示 1)的重复

不幸的是,这篇文章的解决方案对我来说不是一个选择。我无法删除 Devise,因为 User 模型在标准 Web rails 应用程序和应用程序的 api 部分中共享

更新 3 我一直在寻找其他使用标准应用程序使用 API 的方法,并且将设计与门卫一起使用似乎比令牌身份验证更好。设置好后,我又回到了相同的情况

参数数量错误(0 代表 1)

在服务器输出中,我看到以下输出。这是一个有效的用户 ID。

Started GET "/api/v1/users/1" for ::1 at 2015-07-27 20:52:09 +0100 
Processing by Api::V1::UsersController#show as */*   
Parameters: {"id"=>"1"} 
Geokit is using the domain: localhost   
User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]] 
Completed 500 Internal Server Error in 21ms

ArgumentError (wrong number of arguments (0 for 1)):   app/controllers/api/v1/users_controller.rb:5:in `show'

使用无效的 id 我得到这个输出

Started GET "/api/v1/users/134" for ::1 at 2015-07-27 20:55:36 +0100     
Processing by Api::V1::UsersController#show as */*   
Parameters: {"id"=>"134"} 
Geokit is using the domain: localhost   
User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 134]] 
Completed 500 Internal Server Error in 6ms

NoMethodError (undefined method `api_error' for
#<Api::V1::UsersController:0x007fc5a17bf098>):   app/controllers/api_controller.rb:23:in `not_found'

更新 4 插入一些调试语句后,ID 被传递给控制器​​操作,并且正在从数据库中检索用户。

问题在于

respond_with User.find(params[:id])

rails 无法序列化用户。我尝试用另一个没有启用设计的模型替换用户,它可以序列化模型。我不确定为什么设计会在这里引起问题。

4

2 回答 2

1

1:在控制台中验证 FactoryGirl 是否能够正确返回从您的用户工厂创建的用户对象,以便在您的获取请求中不为零。

2:运行 rake routes 以验证其生成的 API 路由是什么样的。我假设如果您之前没有设置过这个,您将需要编辑您的主机文件或在 Mac 上使用 pow 或在 Linux 上使用带有 dnsmasq 的 nginx 之类的东西,以在您的本地开发环境中启用子域支持。然后通过您配置的任何子域(如http://api.myappname.dev/api/v1/users/1.json )手动测试您的 API 控制器,以确保您可以看到它从该 URL 返回有效的 JSON 响应。

路由中 API 命名空间的一个更简洁的示例:

namespace :api, :path => "", :constraints => {:subdomain => "api"} do
  namespace :v1, defaults: { format: 'json' } do

  ...

  end
end
于 2015-07-07T21:12:31.193 回答
0

我花了一段时间才找到解决方案,您可以从上面的帖子中追踪我的想法。

最后,我将问题追溯到使用 devise 的模型无法像普通模型一样序列化。你不能只使用

respont_with User.first 

或类似的东西。设计禁用 activerecord 的默认 to_json 方法。

很多解决方案都谈到了覆盖 to_json 方法或在模型中使用 JBuilder。我不喜欢这样,因为它会限制您可以返回的可能属性。

在查看了to_json的文档后,我决定在选项中简单地传递我想要的属性正是我想要的。

def show
  respond_with User.find(params[:id]).as_json(only: [:id, :name])
end
于 2015-07-29T19:07:10.753 回答