将页面刷新到我的自定义控制器操作时遇到问题。第一次执行操作后,每次刷新页面时,都会遇到ActiveRecord::RecordNotFound
异常。
我在控制器中的动作中编写了这些自定义查询,它们在我的route.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'
我希望能够刷新页面并获得与第一次访问时相同的结果。
答案 0 :(得分:3)
该请求将作为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):
因为它试图查找ID为HealthUnit
的{{1}},而返回especialidades.to_i
,并且由于没有ID为0的记录,您会遇到0
错误
答案 1 :(得分:1)
这是因为,当您刷新路由时,会以id作为特殊对象来显示操作,并尝试使用id="especialidades"
查找HealthUnit,并且不会发现并引发错误
解决这个问题的一种方法是定义约束
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