错误数量的参数 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
我正在尝试在 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