错误数量的参数 0 表示 1 无法使用设计序列化模型

Wrong number of arguments 0 for 1 unable to serialize model using devise

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

controllers > 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

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

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: wrong number of arguments (0 for 1)

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

提前感谢您的帮助

更新 这是 rake routes

的输出
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 这看起来像是 wrong number of arguments (0 for 1) while create my user

的副本

不幸的是,post 的解决方案不适合我。我无法删除 Devise,因为用户模型在标准 Web rails 应用程序和应用程序 api 部分

中共享

更新 3 我正在寻找使用标准应用程序获得 API 的其他方法,并且将 devise 与 doorkeeper 一起使用似乎是比令牌身份验证更好的解决方案。完成设置后,我又回到了

的相同情况

wrong number of arguments (0 for 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" =  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" =  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 无法序列化用户。我尝试用另一个没有启用 Devise 的模型替换 User 并且它可以序列化模型。我不确定为什么设计会导致这里出现问题。

1:在控制台中验证 FactoryGirl 能够正确地 return 从您的用户工厂创建的用户对象,以便在您的 get 请求中不为 nil。

2:运行 rake routes 以验证 API routes 其生成的样子。我假设如果你之前没有设置过它,你将需要编辑你的主机文件或使用类似 pow on mac 或 nginx w/ dnsmasq on Linux 来启用你的子域支持本地开发环境。然后通过您配置的任何子域手动测试您的 API 控制器,例如 http://api.myappname.dev/api/v1/users/1.json 以确保您可以看到它从 URL.

返回有效的 JSON 响应

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

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

  ...

  end
end

我花了一段时间才找到解决方案,你可以从上面的 post 中看出我的想法。

最后我追查到使用devise的模型不能像普通模型一样序列化。你不能只使用

respont_with User.first 

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

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

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

def show
  respond_with User.find(params[:id]).as_json(only: [:id, :name])
end