Если вы хотите создать один контроллер, который обрабатывает несколько типов комментируемых типов, вы можете проверить хэш params на наличие вложенного ключа:
class CommentsController
before_action :set_commentable
private
def set_commentable
raise ActiveRecord::RecordNotFound unless commmentable_key
@commentable = commentable_class.includes(:comments)
.friendly.find(params[commmentable_key])
end
def commmentable_key
@_commmentable_param ||= ["post_id", "video_id"].detect { |key| params[key].present? }
end
def commentable_class
commmentable_key.chomp("_id").classify.constantize
end
end
В этом примере мы проверяем ключи"post_id" и "video_id".Затем мы используем простой набор эвристик, чтобы догадаться, что классом является Post или Video.
Выделяя это в отдельные методы, вы можете переопределить поведение в подклассах.
Не использовать rescue StandardError => e
чтобы отловить ошибку, которая возникает, если запись не найдена.Это анти-шаблон, известный как обработка исключений покемонов .Поймайте только определенные исключения, которые вы знаете, как обрабатывать.
# DON'T DO THIS!
rescue StandardError => e
logger.error "#{e.class.name} : #{e.message}"
@comment = @commentable.comments.build
@comment.errors.add(:base, :recordnotfound, message: "That record doesn't exist. Maybe, it is already destroyed.")
end
Вместо этого используйте rescue_from
, чтобы спасти ActiveRecord::RecordNotFound
, если вы хотите переопределить обработчик 404 по умолчанию в рельсах.Это выручит из действия в вашем контроллере, что является хорошей вещью, поскольку он не должен обрабатывать сценарий, когда ресурс отсутствует.
class CommentsController
rescue_from ActiveRecord::RecordNotFound, with: :not_found
def not_found
render :not_found, status: :not_found
end
end