Думаешь, твой рельсовый проект идеален в плане кода? Нет? Хорошо, что можешь это признать. Я вот знал, что в моём маленьком проекте 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: rails, rails_best_practices, refactoring, ruby
Для получения html надо выполнить:
rails_best_practices -f html .
Но в любом случае - огромное спасибо! Мне очень понравилось, потестил у себя - красота!
Спасибо, исправил эту злую ошибку :)
У тебя код станет еще чище, если ты вынесеш проверку бота в фильтр.
А вот передавать целый объект во флеше - это это жесть.
Тут уже бестпрактики не помогут ;-)
Про фильтр согласен - именно там ему и место.
Про объект во флэше - а как мне еще передать объект в другой экшен, в случае, если мне нужно отобразить ошибки валидации? Flash-объект тут подходит как нельзя кстати, так как он “живет” до следующего экшена.
А зачем вообще делать редирект после ошибки?!
Нужно просто отрендерить форму через render :new
Потому что форма выводится в другом контроллере. Это форма добавления комментария, и она выводится при просмотре поста. И мне хочется, чтобы ошибки валидации комментария показывались именно на этой странице.
Зачем добавлять его в Gemfile проекта, его надо просто поставить через gem install не более
Мне так удобнее, т.к. разрабатываю на 2-х разных машинах. Тупо делаю bundle install и не парюсь.
Всё правильно, что в гем файл.
Добавляете в группу дев и всё, все разработчики в команде счастливы!
group :development
gem “rails_best_practices”
end
Мы в нашем проекте написали простенький guard, который прогоняет rails_best_practices
и reek (https://github.com/kevinrutherford/reek/wiki). И постепенно рефакторим.
rails_best_practices не особо многословен, но его почти всегда стоит послушаться.
reek => делает ваш код еще лучше ( тока стоит предварительно познакомиться с каталогом его запашков)
если знаете еще интересные метрики => посоветуйте