Рефакторинг с использованием rails_best_practices

Думаешь, твой рельсовый проект идеален в плане кода? Нет? Хорошо, что можешь это признать. Я вот знал, что в моём маленьком проекте contemplate, который я мееедленно но верно разрабатываю, были проблемы. В частности - бизнес-логика в контроллере, не DRY-код в некоторых местах и другие проблемы. Теперь я избавился почти от всех них, и помог мне в этом гем rails_best_practices.

Установить и использовать его просто. Добавляешь в Gemfile в группу development строку:

gem "rails_best_practices"

И делаешь bundle install. Затем, в корневой директории проекта запускаешь:

$ rails_best_practices -g

Это сгенерирует конфиг-файл для rails_best_practices. Для начала работы больше настраивать ничего не нужно. Теперь нужно сгенерировать чеклист:

$ rails_best_practices -f html .

После запуска ты получишь файл rails_best_practices_output.html в корне проекта. Просто открываешь его в браузере и смотришь список. Тебе повезет, если он будет пуст. В моем случае было не так - я получил 48 ошибок.

Например, у меня был такой экшен:

def create
  anchor = :new_comment

  # Anti-robot protection
  is_robot = !params[:comment][:name].blank?
  params[:comment].delete :name

  @comment = Comment.new(params[:comment])
  @comment.ip = IPAddr.new(request.env["REMOTE_ADDR"]).to_i
  @comment.user_agent = request.env["HTTP_USER_AGENT"]
  @comment.commentable = @post

  if !is_robot
    if @comment.save
      flash[:notice] = 'Ваш комментарий опубликован.'
      flash.now[:comment] = nil
      anchor = view_context.dom_id(@comment)
    else
      flash[:comment] = @comment
    end
  else
    flash[:comment] = nil
  end

  redirect_to polymorphic_path(@post, :anchor => anchor)
end

После того, как я последовал рекомендациям rails_best_practices, у меня получился более чистый код, так как я вынес имевшуюся бизнес-логику из контроллера в модель:

def create
  anchor = :new_comment

  # Anti-robot protection
  is_robot = !params[:comment][:name].blank?
  params[:comment].delete :name

  @comment = @commentable.comments.build(params[:comment])

  if !is_robot
    if @comment.publish(request.env)
      flash[:notice] = 'Ваш комментарий опубликован.'
      flash.now[:comment] = nil
      anchor = view_context.dom_id(@comment)
    else
      flash[:comment] = @comment
    end
  else
    flash[:comment] = nil
  end

  redirect_to polymorphic_path(@commentable, :anchor => anchor)
end

Вот как выглядит метод Comment#publish

def publish(env)
  raise 'Cannot find associated object for this comment!' if self.commentable.nil?
  require 'ipaddr'

  self.ip = IPAddr.new(env["REMOTE_ADDR"]).to_i
  self.user_agent = env["HTTP_USER_AGENT"]

  save
end

Очень полезный гем. Я неплохо улучшил свой код при помощи его рекомендаций. Гем rails_best_practices также позволяет добавлять свои проверки в чеклист, что позволит проще проводить рефакторинг большого проекта, если вы напишите специфичные для него проверки.

В общем, отличная вещь, рекомендую всем, кто еще не пробовал.

Also interesting

Tags: , , ,

10 Responses to “Рефакторинг с использованием rails_best_practices”

  1. none says:

    Для получения html надо выполнить:
    rails_best_practices -f html .

    Но в любом случае - огромное спасибо! Мне очень понравилось, потестил у себя - красота!

  2. Roman V. Babenko says:

    У тебя код станет еще чище, если ты вынесеш проверку бота в фильтр.
    А вот передавать целый объект во флеше - это это жесть.
    Тут уже бестпрактики не помогут ;-)

    • Ouch! says:

      Про фильтр согласен - именно там ему и место.

      Про объект во флэше - а как мне еще передать объект в другой экшен, в случае, если мне нужно отобразить ошибки валидации? Flash-объект тут подходит как нельзя кстати, так как он “живет” до следующего экшена.

      • Michail says:

        А зачем вообще делать редирект после ошибки?!
        Нужно просто отрендерить форму через render :new

        • Ouch! says:

          Потому что форма выводится в другом контроллере. Это форма добавления комментария, и она выводится при просмотре поста. И мне хочется, чтобы ошибки валидации комментария показывались именно на этой странице.

  3. alvir says:

    Зачем добавлять его в Gemfile проекта, его надо просто поставить через gem install не более

    • Ouch! says:

      Мне так удобнее, т.к. разрабатываю на 2-х разных машинах. Тупо делаю bundle install и не парюсь.

    • Michail says:

      Всё правильно, что в гем файл.
      Добавляете в группу дев и всё, все разработчики в команде счастливы!
      group :development
      gem “rails_best_practices”
      end

  4. niquola says:

    Мы в нашем проекте написали простенький guard, который прогоняет rails_best_practices
    и reek (https://github.com/kevinrutherford/reek/wiki). И постепенно рефакторим.

    rails_best_practices не особо многословен, но его почти всегда стоит послушаться.
    reek => делает ваш код еще лучше ( тока стоит предварительно познакомиться с каталогом его запашков)

    если знаете еще интересные метрики => посоветуйте

Leave a Reply