Как разместить с friendly_id в Rails? - PullRequest
0 голосов
/ 28 января 2019

кто-нибудь, пожалуйста, можете подсказать нам, как публиковать сообщения с friendly_id?

После установки простой системы комментариев все в порядке, но с friednly_id я попытался опубликовать комментарии, которые выкладываются в журнал

Completed 422 Unprocessable Entity in 241ms 

Кажется, из-за неправильной передачи идентификатора в параметры

 Parameters: {"comment"=>{"commentable_id"=>"dde", "comment"=>"swsww", "commentable_type"=>"Post", "parent_id"=>"", "post_id"=>"dde"}, "post_id"=>"dde"}

Более релевантная информация:

Я пытался использовать сообщение непосредственно вместо ресурса, но все жеТо же самое

set_commentable
@commentable = if params[:comment_id]
                   Comment.find_by_id(params[:comment_id])
                 elsif params[:post_id]
                   Post.friendly.find(params[:post_id])
                 end
end

 def set_comment
    @comment = @commentable.comments.friendly.find(params[:id])
  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

  def set_commentable
    resource, id = request.path.split('/')[1, 2]

    @commentable = resource.singularize.classify.constantize.friendly.find(id)
  end

  def set_post
    @post = Post.friendly.find(params[:post_id] || params[:id])
  end

Ожидаемые результаты - публикация комментария без ошибок

stacktrace

1 Ответ

0 голосов
/ 28 января 2019

Если вы хотите создать один контроллер, который обрабатывает несколько типов комментируемых типов, вы можете проверить хэш 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...