with rails from form ruby-on-rails ruby-on-rails-4

ruby-on-rails - from - render rails



Rails 4: responda solo a JSON y no a HTML (9)

respond_to :json crear una API en los rieles 4, y tengo un problema donde Rails devuelve un error de 500 en lugar de un 406 al usar respond_to :json e intentar acceder a la versión html.

Aquí hay un controlador de ejemplo que demuestra el problema:

class PostsController < ApplicationController respond_to :json def index @posts = Post.all end end

También tengo una vista de jbuilder para el index que funciona al acceder a través de JSON. Si intento acceder a la ruta sin la extensión JSON, intenta cargar la plantilla HTML (que no existe) y devuelve un error 500, en lugar de simplemente renderizar JSON o devolver un error 406.

¿Qué podría estar causando esto? Saludos por cualquier ayuda.


Como está utilizando un before_filter, tendrá un 406 No aceptable si se realiza una solicitud para un formato que no está definido.

Ejemplo:

class SomeController < ApplicationController respond_to :json def show @record = Record.find params[:id] respond_with @record end end

La otra forma sería agregar un before_filter para verificar el formato y reaccionar en consecuencia.

Ejemplo:

class ApplicationController < ActionController::Base before_filter :check_format def check_format render :nothing => true, :status => 406 unless params[:format] == ''json'' end end

Pero creo que puedes hacerlo:

respond_to do |format| format.json { render :json => @posts } end

Más información: http://guides.rubyonrails.org/layouts_and_rendering.html


Creo que hay 2 partes aquí:
1) Json solo solicita en rieles
2) json solo respuestas en rieles

1) Configure su controlador de aplicaciones para garantizar solo las solicitudes json

# app/controller/application_controller.rb before_action :ensure_json_request def ensure_json_request return if request.format == :json render :nothing => true, :status => 406 end

2) Configure las rutas de la API de Rails para garantizar solo las respuestas json

# config/routes.rb MyApp::Application.routes.draw do namespace :api, constraints: { format: ''json'' } do namespace :v1 do resources :posts end end end


En Rails 4, debe pasar una lambda para aplicar la restricción en una ruta.

Desafortunadamente, esto NO funcionará porque todavía intentará servir (o intentar servir) una plantilla html ya que el formato es un parámetro opcional:

resources :posts, constraints: { format: ''json'' }

Esto SÍ funciona (usa la lambda):

resources :posts, constraints: lambda { |req| req.format == :json }

Vea la segunda nota (final) en edgeguides.rubyonrails.org/… .


Para evitar cargar la plantilla HTML inexistente, configure el tipo de recurso predeterminado como JSON en config / routes.rb:

resources :posts, :defaults => { :format => :json }


Puede establecerlo teniendo un filtro anterior que establece la solicitud a JSON explícitamente.

request.format = :json


Puedes probar esto, ya que yo también estaba enfrentando este problema y ahora se soluciona al usar esta solución.

class PostsController < ApplicationController respond_to :json def index @posts = Post.all render json: @posts end end


Sugeriría que gem ''active_model_serializers'' . Es realmente increíble y se mantiene limpio.

ApplicationController:

class ApplicationController < ActionController::Base protect_from_forgery with: :exception, if: Proc.new { |c| c.request.format != ''application/json'' } protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == ''application/json'' } end

Rutas:

namespace :api, defaults: { format: :json } do resource :posts end

Controlador de publicaciones:

def index render json: Post.all end


cuando intentes una respuesta en json es porque solo necesitas algunas propiedades. He usado esto

@my_model=Model.select(:attributeN, :attributeN......, attributeN) respond_to do |format| format.json { render json: @my_model } end


constraints no funcionaban para las solicitudes POST y luego probé los defaults para todos.

namespace :api, :defaults => { :format => ''json'' } do namespace :v1 do resources :users do collection do get ''profile'' end end post ''signup'' => ''users#create'' post ''login'' => ''user_sessions#create'' end end