Action Controller: исключение при обновлении страницы - PullRequest
0 голосов
/ 27 мая 2019

У меня возникла проблема при обновлении страницы до моего пользовательского действия контроллера.Каждый раз, когда я обновляю страницу после первого выполнения действия, я получаю исключение ActiveRecord::RecordNotFound.

Я написал эти пользовательские запросы в действиях в моем контроллере, а затем добавил путь к этим действиям в своих маршрутах.rb Это URL, к которому я обращаюсь: http://localhost:3000/health_units/especialidades?specialty=ENFASE Он отлично работает при доступе со страницы индекса, но если я пытаюсь обновить страницу или даже напечатать ее, я получаю эту ошибку.

Это мой контроллер:

class HealthUnitsController < ApplicationController
  before_action :set_health_unit, only: [:show, :edit, :update, :destroy]

  # GET /health_units
  # GET /health_units.json
  def index
    @health_units = HealthUnit.all
  end

  # GET /health_units/1
  # GET /health_units/1.json
  def show
  end

  # GET /health_units/new
  def new
    @health_unit = HealthUnit.new
  end

  # GET /health_units/1/edit
  def edit
  end

  # POST /health_units
  # POST /health_units.json
  def create
    @health_unit = HealthUnit.new(health_unit_params)

    respond_to do |format|
      if @health_unit.save
        format.html { redirect_to @health_unit, notice: 'Health unit was successfully created.' }
        format.json { render :show, status: :created, location: @health_unit }
      else
        format.html { render :new }
        format.json { render json: @health_unit.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /health_units/1
  # PATCH/PUT /health_units/1.json
  def update
    respond_to do |format|
      if @health_unit.update(health_unit_params)
        format.html { redirect_to @health_unit, notice: 'Health unit was successfully updated.' }
        format.json { render :show, status: :ok, location: @health_unit }
      else
        format.html { render :edit }
        format.json { render json: @health_unit.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /health_units/1
  # DELETE /health_units/1.json
  def destroy
    @health_unit.destroy
    respond_to do |format|
      format.html { redirect_to health_units_url, notice: 'Health unit was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  def basic_search
    if params[:keywords].empty?
      redirect_to health_units_path
    else
      @health_units = HealthUnit.where("specialties && :kw or 
        treatments && :kw", kw: params[:keywords].split(' '))
      respond_to do |format|
        format.html { render template: "health_units/index.html.slim" }
        format.json { render template: "health_units/index.json.jbuilder"}
      end
    end
  end

  def list_by_specialties
    if params[:specialty].nil?
      redirect_to health_units_path
    else
      @specialty = params[:specialty]
      @health_units = HealthUnit.where("specialties && ARRAY[?]",
        @specialty)
      respond_to do |format|
        format.html { render template: "health_units/specialty.html.slim" }
        format.json { render template: "health_units/index.json.jbuilder"}
      end
    end
  end

  def list_by_treatments
    if params[:treatments].empty?
      redirect_to health_units_path
    else
      @health_unit = HealthUnit.where("treatments && ?",
        params[:treatments].split(' '))
      respond_to do |format|
        format.html { render template: "health_units/index.html.slim" }
        format.json { render template: "health_units/index.json.jbuilder"}
      end
    end
  end

  def search_by_neighborhood
    if params[:neighborhood].nil?
      redirect_to health_units_path
    else
      @health_units = HealthUnit.where(neighborhood: params[:neighborhood])
      respond_to do |format|
        format.html { render template: "health_units/index.html.slim" }
        format.json { render template: "health_units/index.json.jbuilder"}
      end
    end
  end

  def advanced_search
    @health_unit = HealthUnit.new
  end

  def advanced_search_results
  end


  private
    # Use callbacks to share common setup or constraints between actions.
    def set_health_unit
      @health_unit = HealthUnit.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def health_unit_params
      params.require(:health_unit).permit(:cnes, :name, :address, :neighborhood, :phone, :latitude, :longitude, :description)
    end

end

Это мой routes.rb:

  resources :health_units do
    collection do
      resources :comments, path: 'comentarios'
      post :basic_search, path: 'resultados'
      post :advanced_search, path: 'pesquisar'
      post :list_by_specialties, path: 'especialidades', as: :specialty
      post :list_by_treatments, path: 'atendimentos', as: :treatments
      post :search_by_neighborhood, path: 'bairro', as: :neighborhood
    end

И вот эта ошибка, которую я получаю в своей консоли:

Started GET "/health_units/especialidades?specialty=ENFASE" for 127.0.0.1 at 2019-05-27 03:29:07 -0300
Processing by HealthUnitsController#show as HTML
  Parameters: {"specialty"=>"ENFASE", "id"=>"especialidades"}
  HealthUnit Load (0.5ms)  SELECT  "health_units".* FROM "health_units" WHERE "health_units"."id" = $1 LIMIT $2  [["id", 0], ["LIMIT", 1]]
  ↳ app/controllers/health_units_controller.rb:127
Completed 404 Not Found in 3ms (ActiveRecord: 0.5ms)



ActiveRecord::RecordNotFound (Couldn't find HealthUnit with 'id'=especialidades):

app/controllers/health_units_controller.rb:127:in `set_health_unit'
Started GET "/favicon.ico" for 127.0.0.1 at 2019-05-27 03:29:07 -0300

ActionController::RoutingError (No route matches [GET] "/favicon.ico"):

actionpack (5.2.3) lib/action_dispatch/middleware/debug_exceptions.rb:65:in `call'
actionpack (5.2.3) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
railties (5.2.3) lib/rails/rack/logger.rb:38:in `call_app'
railties (5.2.3) lib/rails/rack/logger.rb:26:in `block in call'
activesupport (5.2.3) lib/active_support/tagged_logging.rb:71:in `block in tagged'
activesupport (5.2.3) lib/active_support/tagged_logging.rb:28:in `tagged'
activesupport (5.2.3) lib/active_support/tagged_logging.rb:71:in `tagged'
railties (5.2.3) lib/rails/rack/logger.rb:26:in `call'
actionpack (5.2.3) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
actionpack (5.2.3) lib/action_dispatch/middleware/request_id.rb:27:in `call'
rack (2.0.7) lib/rack/method_override.rb:22:in `call'
rack (2.0.7) lib/rack/runtime.rb:22:in `call'
activesupport (5.2.3) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
actionpack (5.2.3) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (5.2.3) lib/action_dispatch/middleware/static.rb:127:in `call'
rack (2.0.7) lib/rack/sendfile.rb:111:in `call'
railties (5.2.3) lib/rails/engine.rb:524:in `call'
puma (3.12.1) lib/puma/configuration.rb:227:in `call'
puma (3.12.1) lib/puma/server.rb:660:in `handle_request'
puma (3.12.1) lib/puma/server.rb:474:in `process_client'
puma (3.12.1) lib/puma/server.rb:334:in `block in run'
puma (3.12.1) lib/puma/thread_pool.rb:135:in `block in spawn_thread'

Я хотел быиметь возможность обновить страницу и получить тот же результат, что и при первом обращении к ней.

Ответы [ 2 ]

3 голосов
/ 27 мая 2019

Запрос обрабатывается как GET запрос.

Started GET "/health_units/especialidades?specialty=ENFASE" for 127.0.0.1 at 2019-05-27 03:29:07 -0300
Processing by HealthUnitsController#show as HTML

rails ожидает его как POST запрос в соответствии с определенным маршрутом

post :list_by_specialties, path: 'especialidades', as: :specialty

Таким образом, вместо сопоставления HealthUnitsController#list_by_specialties он соответствует маршруту для HealthUnitsController#show

Вам нужно посмотреть, почему ваш запрос выглядит как GET, а не POST.Как только вы исправите это, он будет работать правильно

Причина, по которой вы получаете ActiveRecord::RecordNotFound ошибку

ActiveRecord::RecordNotFound (Couldn't find HealthUnit with 'id'=especialidades):

Поскольку он пытается найти HealthUnit с идентификаторомespecialidades.to_i, который возвращает 0, и поскольку нет записи с id = 0, вы получите ActiveRecord::RecordNotFound error

1 голос
/ 27 мая 2019

Это происходит потому, что при обновлении маршруты показывают действие, принимающее id в качестве especialidades, и оно пытается просмотреть HealthUnit с id="especialidades", но не находит и не вызывает ошибку

так что одним из способов решения этой проблемы является определение ограничений

class RandomConstraint
  def matches?(request)
    return false unless request.path_parameters[:id].present?
  end
end

get :list_by_specialties, path: 'especialidades', as: :specialty, constraints: RandomConstraint.new
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...