Posts Tagged ‘rails_best_practices’

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

Четверг, Сентябрь 29th, 2011

Думаешь, твой рельсовый проект идеален в плане кода? Нет? Хорошо, что можешь это признать. Я вот знал, что в моём маленьком проекте 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 также позволяет добавлять свои проверки в чеклист, что позволит проще проводить рефакторинг большого проекта, если вы напишите специфичные для него проверки.

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