Heroku выдает внутреннюю ошибку сервера только в одном из трех действий в моем приложении API - PullRequest
0 голосов
/ 04 декабря 2018

Я создал API, который при вызове обслуживает 3 разных набора данных.Каждая коллекция разной категории, а именно: рестораны, пляжные рестораны и кафе.

Вот мои маршруты:

Rails.application.routes.draw do
  devise_for :users
  namespace :api, defaults: { format: :json } do
    namespace :v1 do
      resources :ads, only: [ :index, :show ] do
        collection do
          get 'restaurant', to: 'ads#restaurant'
          get 'beach_restaurant', to: 'ads#beach_restaurant'
          get 'cafe', to: 'ads#cafe'
        end
      end
    end
  end
  root to: 'pages#home'

Вот что я сделал в контроллере API:

class Api::V1::AdsController < Api::V1::BaseController
  before_action :set_ad, only: [ :show ]

  def index
    @ads = policy_scope(Subcategory.find_by(nombre: "Restaurantes").ads)
  end

  def restaurant
    @restaurants = policy_scope(Subcategory.find_by(nombre: "Restaurantes").ads)
  end

  def beach_restaurant
    @beach_restaurants = policy_scope(Subcategory.find_by(nombre: "Restaurantes de playa").ads)
  end

  def cafe
    @cafes = policy_scope(Subcategory.find_by(nombre: "Cafés y Heladerías").ads)
  end

  def show
  end

  private

  def set_ad
    @ad = Ad.find(params[:id])
    authorize @ad
  end
end

Это в моем BaseController:

class Api::V1::BaseController < ActionController::API
  include Pundit

  after_action :verify_authorized, except: [:index, :restaurant, :beach_restaurant, :cafe]
  after_action :verify_policy_scoped, only: [:index, :restaurant, :beach_restaurant, :cafe]

  rescue_from StandardError,                with: :internal_server_error
  rescue_from Pundit::NotAuthorizedError,   with: :user_not_authorized
  rescue_from ActiveRecord::RecordNotFound, with: :not_found

  private

  def user_not_authorized(exception)
    render json: {
      error: "Unauthorized #{exception.policy.class.to_s.underscore.camelize}.#{exception.query}"
    }, status: :unauthorized
  end

  def not_found(exception)
    render json: { error: exception.message }, status: :not_found
  end

  def internal_server_error(exception)
    if Rails.env.development?
      response = { type: exception.class.to_s, message: exception.message, backtrace: exception.backtrace }
    else
      response = { error: "Internal Server Error" }
    end
    render json: response, status: :internal_server_error
  end
end

А потом я сделал 3 разных представления: restaurant.json.jbuilder, beach_restaurant.json.jbuilder и cafe.json.jbuilder

restaurant.json.jbuilder

json.array! @restaurants do |restaurant|
  json.extract! restaurant,
  :id,
  :empresa,
  :direccion_principal,
  :tel,
  :email_principal,
  :web,
  :facebook,
  :instagram,
  :twitter,
  :isla
end

beach_restaurant.json.jbuilder

json.array! @beach_restaurants do |beach_restaurant|
  json.extract! beach_restaurant,
  :id,
  :empresa,
  :direccion_principal,
  :tel,
  :email_principal,
  :web,
  :facebook,
  :instagram,
  :twitter,
  :isla
end

cafe.json.jbuilder

json.array! @cafes do |cafe|
  json.extract! cafe,
  :id,
  :empresa,
  :direccion_principal,
  :tel,
  :email_principal,
  :web,
  :facebook,
  :instagram,
  :twitter,
  :isla
end

Эти 3 действия работают нормально, когда я запрашиваю их на локальном сервере с помощью Postman, но после развертывания в Heroku действие кафе создает внутреннюю ошибку сервера(статус: 500).Я не понимаю, как это возможно, потому что кафе настроено точно так же, как действие restaurant и beach_restaurant, и эти две работы работают над герою.У кого-то есть идея, почему это так?

Это то, что heroku logs --tail показывает:

2018-12-04T06:19:38.704997+00:00 heroku[router]: at=info method=GET path="/api/v1/ads/cafe" host=my-app.herokuapp.com request_id=97694e3f-91fe-41fc-b2fc-de96d41d134d fwd="83.54.89.18" dyno=web.1 connect=0ms service=470ms status=500 bytes=274 protocol=https
2018-12-04T06:19:38.578597+00:00 app[web.1]: D, [2018-12-04T06:19:38.578458 #4] DEBUG -- : [97694e3f-91fe-41fc-b2fc-de96d41d134d]    (41.7ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
2018-12-04T06:19:38.703397+00:00 app[web.1]: D, [2018-12-04T06:19:38.701104 #4] DEBUG -- : [97694e3f-91fe-41fc-b2fc-de96d41d134d]   Subcategory Load (39.7ms)  SELECT  `subcategorias`.* FROM `subcategorias` WHERE `subcategorias`.`nombre` = 'Cafés y Heladerías' LIMIT 1
2018-12-04T06:19:38.703401+00:00 app[web.1]: I, [2018-12-04T06:19:38.702341 #4]  INFO -- : [97694e3f-91fe-41fc-b2fc-de96d41d134d] Completed 500 Internal Server Error in 462ms (Views: 0.4ms | ActiveRecord: 121.7ms)

1 Ответ

0 голосов
/ 04 декабря 2018

Я исправил проблему, используя .find () в контроллере вместо .find_by ().Я думаю, что как-то поиск строкового имени категории не удается, когда он на Heroku.В этом случае лучше искать категорию по ее идентификатору.

Так что правильный путь:

def beach_restaurant
    @cafes = policy_scope(Subcategory.find(3).ads)
end
...