前言:
我研究了如何对API进行版本控制,并找到了几种方法.我决定尝试peter williams的建议并创建新的供应商mime类型来指定版本和格式.我无法在"导轨方式"之后找到这样做的明确说明,所以我拼凑了几个地方的信息.我能够让它工作,但渲染器处理Widget数组vs Widget实例的方式有一些愚蠢respond_with
.
基本步骤和问题:
我注册了mime类型,并在xml和json中为ApplicationController添加了版本1的渲染器,渲染了模型中的渲染器to_myproj_v1_xml
和to_myproj_v1_json
方法. respond_with(@widget)
工作正常,但respond_with(@widgets)
抛出一个HTTP/1.1 500 Internal Server Error
说法"模板丢失".
解决方法:
"缺少模板"表示没有调用渲染,也不存在匹配的模板.偶然的,我发现它正在寻找一种类方法......所以我想出了下面的代码,但是我对它并不满意.愚蠢主要在xml = obj.to_myproj_v1_xml(obj)
模型中并且与模型中的重复相关.
我的问题是 - 有没有人以稍微清洁的方式做过类似的事情?
- =更新代码= -
config/initializers/mime_types.rb:
Mime::Type.register 'application/vnd.com.mydomain.myproj-v1+xml', :myproj_v1_xml
Mime::Type.register 'application/vnd.com.mydomain.myproj-v1+json', :myproj_v1_json
Run Code Online (Sandbox Code Playgroud)
app/controllers/application_controller.rb:
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :authenticate
ActionController.add_renderer :myproj_v1_xml do |obj, options|
xml = obj.to_myproj_v1_xml
self.content_type ||= Mime::Type.lookup('application/vnd.com.mydomain.myproj-v1+xml')
self.response_body = xml
end
ActionController.add_renderer :myproj_v1_json do |obj, options|
json = obj.to_myproj_v1_json
self.content_type ||= Mime::Type.lookup('application/vnd.com.mydomain.myproj-v1+json')
self.response_body …
Run Code Online (Sandbox Code Playgroud) 我正在使用respond_with
,所有内容都正确连接,以正确获取数据.我想自定义的返回json
,xml
以及foobar
格式在干燥的方式,但我无法弄清楚如何使用有限的做:only
和:include
.当数据很简单时,这些都很棒,但是对于复杂的发现,它们不符合我的要求.
可以说我有一个帖子哪个has_many
图像
def show
@post = Post.find params[:id]
respond_with(@post)
end
Run Code Online (Sandbox Code Playgroud)
我希望将图像包含在响应中,以便我可以这样做:
def show
@post = Post.find params[:id]
respond_with(@post, :include => :images)
end
Run Code Online (Sandbox Code Playgroud)
但我真的不想发送整个图像对象,只是网址.除此之外,我真的希望能够做到这样的事情(伪代码):
def show
@post = Post.find params[:id]
respond_with(@post, :include => { :foo => @posts.each.really_cool_method } )
end
def index
@post = Post.find params[:id]
respond_with(@post, :include => { :foo => @post.really_cool_method } )
end
Run Code Online (Sandbox Code Playgroud)
......但是一切都干了.在较旧的rails项目中,我使用XML构建器来自定义输出,但是在json,xml,html中复制它看起来不对.我不得不想象铁路专家在Rails 3中放了一些东西,我没有意识到这种行为.想法?
我正在创建一个简单的Rails 3应用程序,我遇到了以下问题.这让我很沮丧.
我的模特:
class Vehicle < ActiveRecord::Base
has_many :vehicle_pictures, :dependent => :destroy
def
class VehiclePicture < ActiveRecord::Base
belongs_to :vehicle
end
Run Code Online (Sandbox Code Playgroud)
我的routes.rb:
MyApp::Application.routes.draw do
resources :vehicles do
resources :pictures, :controller => :vehicle_pictures
end
end
Run Code Online (Sandbox Code Playgroud)
我的rake routes
输出:
vehicle_pictures GET /vehicles/:vehicle_id/pictures(.:format) {:action=>"index", :controller=>"vehicle_pictures"}
POST /vehicles/:vehicle_id/pictures(.:format) {:action=>"create", :controller=>"vehicle_pictures"}
new_vehicle_picture GET /vehicles/:vehicle_id/pictures/new(.:format) {:action=>"new", :controller=>"vehicle_pictures"
edit_vehicle_picture GET /vehicles/:vehicle_id/pictures/:id/edit(.:format) {:action=>"edit", :controller=>"vehicle_pictures"}
vehicle_picture GET /vehicles/:vehicle_id/pictures/:id(.:format) {:action=>"show", :controller=>"vehicle_pictures"}
PUT /vehicles/:vehicle_id/pictures/:id(.:format) {:action=>"update", :controller=>"vehicle_pictures"}
DELETE /vehicles/:vehicle_id/pictures/:id(.:format) {:action=>"destroy", :controller=>"vehicle_pictures"}
Run Code Online (Sandbox Code Playgroud)
我的vehicle_pictures_controller.rb:
class VehiclePicturesController < ApplicationController
before_filter :find_vehicle
respond_to :html, :json, :xml …
Run Code Online (Sandbox Code Playgroud) 利用ActionController的新respond_with
方法......当action(保存)成功时以及何时不成功时,它如何确定要呈现的内容?
我问,因为我试图获得一个脚手架生成的规范(包括在下面),如果只是为了让我能理解它.该应用程序工作正常,但奇怪/carriers
的是,当验证失败时,它似乎正在渲染(至少是浏览器的URL所说的).然而,规范期待"new"
(我也是如此),而是接受<"">
.如果我更改规格以期望""
它仍然失败.
当它呈现/carriers
该页面时,会显示错误验证失败的字段旁边的error_messages.
任何熟悉的人都能respond_with
看到这里发生了什么吗?
#carrier.rb
validates :name, :presence => true
#carriers_controller.rb
class CarriersController < ApplicationController
respond_to :html, :json
...
def new
respond_with(@carrier = Carrier.new)
end
def create
@carrier = Carrier.new(params[:carrier])
flash[:success] = 'Carrier was successfully created.' if @carrier.save
respond_with(@carrier)
end
Run Code Online (Sandbox Code Playgroud)
规格失败:
#carriers_controller_spec.rb
require 'spec_helper'
describe CarriersController do
def mock_carrier(stubs={})
(@mock_carrier ||= mock_model(Carrier).as_null_object).tap do |carrier|
carrier.stub(stubs) unless stubs.empty?
end
end
describe "POST create" do
describe "with invalid …
Run Code Online (Sandbox Code Playgroud) 我试图通过合并来干扰控制器respond_with
.当我这样做时,遵循Railscast中的一些指示,我得到的东西大部分都在工作.问题在于删除资源后的重定向...应该重定向到people_url
...而是尝试加载特定资源.
我找到的示例代码看起来像这样......但是它尝试加载刚删除的资源失败了:
# app/controllers/people_controller.rb
class PeopleController < ApplicationController
respond_to :html, :xml
def destroy
@person = Person.find(params[:id])
flash[:notice] = 'Successfully deleted person.' if @person.destroy
respond_with(@person) # <== spec fails here
end
end
Run Code Online (Sandbox Code Playgroud)
改变最后一行respond_with(@people)
也不起作用(虽然我曾希望它会...)
经过深入挖掘并尽力了解事情,我确实让事情发生了(至少看起来如此.规格传递.app功能)用这个:
respond_with(@person, :location => people_url) # <== now it works
Run Code Online (Sandbox Code Playgroud)
那么,这是处理这个问题的正确方法吗?似乎有了所有'魔法'背后的response_with它会知道删除后它不能重定向到自己?我也认为这个(7种基本的RESTful CRUD方法之一)将是非常基本和基本的,所以很多例子会比比皆是......但我找不到很多,除了那些暗示代码不起作用的代码我.
希望有人可以帮助我理解这里发生的铁轨'魔力'所以当我在路上爆炸时,我不会感到惊讶.
当从Rails 3.1应用程序返回包含"type"属性作为JSON的对象时,似乎不包括"type"属性.假设我有以下内容:
具有相应STI表Animal的模型.继承Animal的Cat,Dog和Fish模型.
通过JSON返回Animal时,我希望包含"type"列,但这不会发生:
jQuery.ajax("http://localhost:3001/animals/1", {dataType: "json"});
Run Code Online (Sandbox Code Playgroud)
收益率:
responseText: "{"can_swim":false,"created_at":"2012-01-20T17:55:16Z","id":1,"name":"Fluffy","updated_at":"2012-01-20T17:55:16Z","weight":9.0}"
Run Code Online (Sandbox Code Playgroud)
看来这是to_json的一个问题:
bash-3.2$ rails runner 'p Animal.first.to_yaml'
"--- !ruby/object:Cat\nattributes:\n id: 1\n type: Cat\n weight: 9.0\n name: Fluffy\n can_swim: false\n created_at: 2012-01-20 17:55:16.090646000 Z\n updated_at: 2012-01-20 17:55:16.090646000 Z\n"
bash-3.2$ rails runner 'p Animal.first.to_json'
"{\"can_swim\":false,\"created_at\":\"2012-01-20T17:55:16Z\",\"id\":1,\"name\":\"Fluffy\",\"updated_at\":\"2012-01-20T17:55:16Z\",\"weight\":9.0}"
Run Code Online (Sandbox Code Playgroud)
有谁知道这种行为背后的原因,以及如何覆盖它?
我有一个非常标准的验证方法
private
def authenticate_user
@current_user = User.find_by_authentication_token(params[:token])
unless @current_user
error = { :error => "Invalid token." }
respond_with(error, :status => 401 )
end
end
Run Code Online (Sandbox Code Playgroud)
我正在调用API以确保身份验证失败.
我收到一个错误说明
ArgumentError (Nil location provided. Can't build URI.):
app/controllers/api/v1/base_controller.rb:13:in `authenticate_user'
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
我正在尝试为我的Rails 3应用程序创建一个JSONP API.现在在我的控制器中,我有很多遵循这种模式的动作:
# This is from my users_controller.rb, as an example
def index
@users = User.all
respond_with(@users, :callback => params[:callback])
end
Run Code Online (Sandbox Code Playgroud)
虽然这是按原样运作的,但我想通过不必重复:callback => params[:callback]
每一个动作的呼叫来干它respond_with
.我怎样才能做到这一点?
更新:有一件事我已经意识到我的上述代码是丑陋的,该:callback => params[:callback]
选项将被传递给任何响应格式,而不仅仅是JSON.以下代码可能更正确:
def index
@users = User.all
respond_with(@users) do |format|
format.json { render :json => @users, :callback => params[:callback]}
end
end
Run Code Online (Sandbox Code Playgroud)
我有几种方法可以解决这个问题,但我无法弄清楚如何使它们工作:
render
(可能在应用程序控制器中),以便它接受:jsonp
自动包含:callback => params[:callback]
参数的选项.这样我可以将上面的代码更改为以下代码,这有点短:def index
@users = User.all
respond_with(@users) do |format|
format.json { render :jsonp => @users}
end
end …
Run Code Online (Sandbox Code Playgroud) 我在我的控制器中遇到了一个奇怪的行为。他们似乎偶尔想要重定向而不是呈现 json 响应。
respond_to :json, :html, :js
def create
@favorite = current_user.favorites.build(:location_id=>params[:location_id])
if @favorite.save
respond_with(@favorite)
else
respond_with(@favorite.errors)
end
end
Run Code Online (Sandbox Code Playgroud)
我认为它大部分时间都有效,但今天我收到了这个错误的通知:
NoMethodError: #<FavoritesController:0x00000006171dc0> 的未定义方法 `favorite_url'
params 哈希记录为:
{"format"=>"json",
"action"=>"create",
"user_id"=>"56",
"auth_token"=>"iGSty8CMIaWsbShYZEtw",
"location_id"=>"47943",
"controller"=>"favorites"}
Run Code Online (Sandbox Code Playgroud)
特别奇怪,因为它似乎大部分时间都在工作......我已经改变了我的一些其他控制器来使用旧的 format.json { render :json => @object } 语法,但如果可能的话我想避免这种情况.
这怎么可能?
我有一个简单的角度轨道应用程序,我试图连线.
这是我的rails控制器:
class ItemsController < ApplicationController
respond_to :json, :html
def index
@items = Item.order(params[:sort]).page(params[:page]).per(15)
end
def show
@item = Item.where(params[:id])
if @item.empty?
flash[:alert] = "Item number #{params[:id]} does not exist"
else
respond_with @item do |format|
format.json { render :layout => false }
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
我一直收到ActionView::MissingTemplate
错误,因为rails一直试图提供erb模板.我不想要模板!! 我只想要json.有人可以给出明确的respond_to/respond_with语法,这将永远摆脱我的模板吗?
respond-with ×10
json ×3
dry ×2
activerecord ×1
api ×1
controller ×1
jsonp ×1
response ×1
routing ×1
rspec ×1
versioning ×1