Mik*_*keL 9 layout json ruby-on-rails jbuilder
在我的rails 3.2应用程序中,我使用jbuilder来呈现来自我的JSON api的响应.
我想为所有API响应提供一个通用结构,并且布局可能是保持我的视图DRY的可能解决方案.
例如:我希望每个回复都是以下形式:
{
status: "ok|error|redirect",
data: { ... JSON specific to the current view ... },
errors: [ ... ],
notes: [ ... ]
}
Run Code Online (Sandbox Code Playgroud)
(其中数据的值是视图提供的json结构,其他所有内容都来自布局)
但是:我无法正确地让jbuilder布局屈服于视图.
# in layout
json.data yield
# in view
json.some "value"
Run Code Online (Sandbox Code Playgroud)
结果是:
{"data":"{\"some\":\"value\"}"} # arg! my json has become a string
Run Code Online (Sandbox Code Playgroud)
以另一种方式尝试:
# in layout
yield
# in view
json.data do |json|
json.some "value"
end
Run Code Online (Sandbox Code Playgroud)
结果是 :
{}
Run Code Online (Sandbox Code Playgroud)
有没有人用jbuilder或其他json模板gem /方法做到这一点?
这个juilder github问题表明这是可能的,但表明其他人也有类似的问题.
我看到rabl(https://github.com/nesquena/rabl/)应该支持布局(https://github.com/nesquena/rabl/wiki/Using-Layouts),但我决定不使用由于其他原因(rabl使复杂的json结构成为一场噩梦,特别是在试图控制对象根等时).
sor*_*ens 12
我会根据我们提出的解决方案为您提供替代方案:
# app/helpers/application_helper.rb
module ApplicationHelper
def envelope(json, status, errors, notes)
json.status status
json.data do
yield if block_given?
end
json.errors errors
json.notes notes
end
end
Run Code Online (Sandbox Code Playgroud)
然后,在视图中,您可以调用信封并包含您的json代码,如:
# app/views/api/v1/test/show.json.jbuilder
envelope(json, "OK" ) do
json.some 'value'
end
Run Code Online (Sandbox Code Playgroud)
Dob*_*hev 10
你可以通过这种方式做到这一点
# api.v1.json.jbuilder - layout
json.request do
json.message "your message"
json.status 200
end
json.data JSON.parse(yield)
# show.json.jbuilder - action view
json.name 'Some item name'
Run Code Online (Sandbox Code Playgroud)
迟到的答案,但帮助我得到了我想要的...
成功结果:
{ "something": {"id": 42, "message": "hello"}, "status": "ok", "errors": [] }
Run Code Online (Sandbox Code Playgroud)
错误结果:
{ "something": null, "status": "error", "errors": ["could not do the thing"] }
Run Code Online (Sandbox Code Playgroud)
码:
应用程序/控制器/ API/V1/base_controller.rb
class Api::V1::BaseController < ActionController::API
layout 'api/v1/application'
before_action :setup_layout_elements
def setup_layout_elements
@status = :ok
@errors = []
end
def error!(message)
@status = :error
@errors << message
nil
end
end
Run Code Online (Sandbox Code Playgroud)
应用程序/控制器/ API/V1/some_controller.rb
class Api::V1::SomeController < Api::V1::BaseController
def index
@something = begin
possibly_error_causing_code
rescue
error!('could not do the thing')
end
render builder: 'api/v1/something/index'
end
end
Run Code Online (Sandbox Code Playgroud)
应用程序/视图/布局/ API/V1/application.json.jbuilder
json.merge! JSON.parse(yield)
json.status @status
json.errors @errors
Run Code Online (Sandbox Code Playgroud)
应用程序/视图/ API/V1 /事/ index.json.jbuilder
json.something do
json.id @something.id
json.message @something.to_s
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8417 次 |
| 最近记录: |