Как обращаться с ActiveRecord:: RecordNotFound в контроллере rails? - программирование
Подтвердить что ты не робот

Как обращаться с ActiveRecord:: RecordNotFound в контроллере rails?

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

def show
  begin
    @userEvents = current_user.event
    @event = @userEvents.find(params[:id])
  rescue ActiveRecord::RecordNotFound  
    redirect_to :controller => "main", :action => "index"
  end

  respond_to do |format|
    format.html # show.html.erb
    format.json { render json: @event }
  end
end

Если событие не найдено для пользователя, это означает, что он играл с URL-адресом, и событие, которое он пытается получить, не принадлежит ему. Я хочу либо перенаправить его на главную страницу, либо просто отобразить страницу с ошибкой, что событие не найдено. Если я попытаюсь запустить код выше, эта ошибка срабатывает:

AbstractController::DoubleRenderError in EventsController#show 

Какой лучший способ исправить это?

4b9b3361

Ответ 1

Положите return после перенаправления

begin
 @userEvents = current_user.event
 @event = @userEvents.find(params[:id])
rescue ActiveRecord::RecordNotFound  
 redirect_to :controller => "main", :action => "index"
 return
end

Ответ 2

Вызов redirect_to не возвращается из вашего метода действий, поэтому переход к блоку respond_to вызывает DoubleRenderError. Один из способов исправить это:

redirect_to :controller => "main", :action => "index" and return

Однако лучшим решением может быть спасти от это исключение декларативно или просто позволить ему распространяться на клиента. Первые выглядят так:

class YourController < ActionController::Base

  rescue_from ActiveRecord::RecordNotFound, with: :dude_wheres_my_record

  def show
    # your original code without the begin and rescue
  end

  def dude_where_my_record
    # special handling here
  end
end

Если вы просто разрешите исключение, пользователь увидит страницу public/404.html в рабочем режиме.

Ответ 3

В контроллере приложений напишите:

    rescue_from (ActiveRecord::RecordNotFound) { |exception| handle_exception(exception, 404) }

   protected

    def handle_exception(ex, status)
        render_error(ex, status)
        logger.error ex   
    end

    def render_error(ex, status)
        @status_code = status
        respond_to do |format|
          format.html { render :template => "error", :status => status }
          format.all { render :nothing => true, :status => status }
       end
    end

Создать страницу error.html.erb

<div class="page-header">
  <h1>
    <%= t "errors.#{@status_code}.heading" %>
    <small><%= t "errors.#{@status_code}.subheading" %></small>
  </h1>
</div>
<p><%= t "errors.#{@status_code}.description" %></p>
<% if defined? root_path %>
  <%= link_to t(:return_to_home), root_path %>
<% end %>

и в en.yml

en:
  errors:
    "404":
      description: "The page you are looking for does not exist!"
      heading: "Record not found"
      subheading: ""