#ruby-on-rails #ruby-on-rails-4
#ruby-on-rails #ruby-on-rails-4
Вопрос:
Я реализую RESTful API с использованием RoR. Здесь мой UsersController
:
class ApplicationController < ActionController::API
[...]
end
module Api
module V1
class UsersController < ApplicationController
respond_to :json
def create
@user = User.new(user_params)
@user.save
respond_with @user, :location => api_v1_user_url(@user)
end
def show
@user = User.find(params[:id])
respond_with @user
end
end
end
end
Если я опущу @user
параметр из :location => api_v1_user_url(@user)
in UsersController#create
, т.Е. у меня это так:
respond_with @user, :location => api_v1_user_url
Я получаю следующую ошибку:
ActionController::UrlGenerationError in Api::V1::UsersController#create
No route matches {:action=>"show", :controller=>"api/v1/users", :format=>"json"} missing required keys: [:id]
Я просто добавил @user
параметр в api_v1_user_url
на догадке после того, как увидел эту ошибку, и она работает.
Мой вопрос в том, что здесь происходит? Я не понимаю, зачем мне нужно передавать @user
, когда большинство примеров, которые я видел, не предполагают передачу объекта @user
в :location
атрибут.
Вывод rake routes
является следующим:
$ rake routes
Ignoring bcrypt-3.1.7 because its extensions are not built. Try: gem pristine bcrypt-3.1.7
Prefix Verb URI Pattern Controller#Action
api_v1_users GET /api/v1/users(.:format) api/v1/users#index {:format=>"json"}
POST /api/v1/users(.:format) api/v1/users#create {:format=>"json"}
new_api_v1_user GET /api/v1/users/new(.:format) api/v1/users#new {:format=>"json"}
edit_api_v1_user GET /api/v1/users/:id/edit(.:format) api/v1/users#edit {:format=>"json"}
api_v1_user GET /api/v1/users/:id(.:format) api/v1/users#show {:format=>"json"}
PATCH /api/v1/users/:id(.:format) api/v1/users#update {:format=>"json"}
PUT /api/v1/users/:id(.:format) api/v1/users#update {:format=>"json"}
DELETE /api/v1/users/:id(.:format) api/v1/users#destroy {:format=>"json"}
static_index GET /static/index(.:format) static#index
root GET / static#index
Другое место, которое я видел (просто чтобы назвать другое):
Ответ №1:
Причина в том, что api_v1_user_url
or api_v1_user_path
предназначены для одного экземпляра, и вам нужно передать имя id
этого пользователя, которое он должен искать и отображать. Следовательно, почему вы получили сообщение об ошибке.
В примерах, которые вы, вероятно, видели api_v1_users_url
или api_v1_users_path
которые отображают всех пользователей. Обратите внимание на users_ vs user_
Комментарии:
1. Это имеет смысл, но я не вижу упоминания о передаче
id
even в документах api здесь: api.rubyonrails.org/classes/ActionController/Responder.html2. Идентификатор извлекается при передаче
@user
объекта, потому что действие show требует использования идентификатора (здесь также используется магия rails). Также, когда вы создаете каркас, в моем случае дляPost
model , вы получаете это:<%= link_to 'Show', post %>
и<%= link_to 'Edit', edit_post_path(post) %>
которые указывают, что при передаче объекта получается идентификатор.