Офигенный баг AR колбеков
Илья • 27 мая 2009 г.
Сегодня потратил полтора часа, пытаясь починить проблему с before_destroy колбеком в одной из моделей. По
В итоге всё оказалось весьма банально. Каждая рельсовая ассоциация с параметром :dependent => :destroy добавляет в модель новый before_destroy колбек. Колбеки для модели Рельса никак не сортирует и запускает по правилу «первый добавился, первый выстрелил». Следовательно если ваши before_destroy прописаны в модели после ассоциаций с :dependent => :destroy, то и запустятся они после того как ассоциации будут удалены. В такие моменты я ненавижу Рельсы..
Так что сегодня выучил для себя новый урок: декларации before_destroy должны идти всегда перед ассоциациями, у которых установлен :dependent => :destroy.
То есть не так:
class Account < ActiveRecord::Base
has_many :users, :dependent => :destroy
before_destroy :do_something_funky_with_users
end
А вот так:
class Account < ActiveRecord::Base
before_destroy :do_something_funky_with_users
has_many :users, :dependent => :destroy
end
Почему rescue_from пропускает некоторые исключения?
Илья • 10 апреля 2009 г.
Если вы пользовались rescue_from, то наверное замечали, что по
В общем сегодня как раз решал такую проблему в Бинстолке и решил сделать из своего решения маленький плугин. Плугин получился очень простой, всего пару строчек кода, зато работает как надо. Теперь все исключения, не важно где они выпрыгнули — во вьюшках или контроллерах — будут прекрасно обрабатываться вашими rescue_from хендлерами.
Читайте ридми на гитхабе и пользуйтесь на здоровье:
http://github.com/iSabanin/rescue_from_templates_exceptions/tree/master
P.S. — если вы считаете что этот плугин должен быть частью Rails Core, пишите в комментариях своё мнение.
Поддержка вложенных массивов, массивов с числами и символами в ActiveResource
Илья • 2 апреля 2009 г.
Делая API для Бинстолка, столкнулся с большой тупостью ActiveResource, после которой даже подумал перейти на RestClient. Оказалось что ARes не умеет принимать вложенные массивы, или массивы, в которых содержатся символы или цифры. Он умеет загружать только плоские массивы со строками и ничего больше.
Например такой код выбросит исключение:
# changeset объект класса ActiveResource
changeset.load {:files => [["/trunk/bla", "add"], ["/trunk/ble", "delete"]]}
# => ArgumentError: expected an attributes Hash, got ["/trunk/bla", "add"]
То же самое с символами и числами. Простой массив с числами передать ARes не получится.
Абсурд полный! Особенно для библиотеки, которая вроде как перевалила за вторую версию.
В общем я запостил два пачта (под одним тикетом) на лайтхаус: Support for loading nested arrays, numbers and symbols in ActiveResource.
Буду благодарен за плюсики. Сделаем мир лучше, спасём бегемотов в Африке.
Кастомные названия аттрибутов модели
Илья • 9 сентября 2008 г.
Всем известно как изменить текст сообщения об ошибке валидации модели. Но не всем известен трюк, как изменить само название атрибута, которое будет отображаться в сообщении об ошибке. Рельсы, к сожалению, нам не предоставляют простого пути решения.
Итак, проблема:

Сообщение об ошибке на русском языке, в то время как название атрибута на английском (причём часто на ломаном английском,
Для того чтобы решить эту проблему, нам понадобиться один маленький файлик — humanized_attributes.rb. Бросаем его в lib/ и подключаем в environment.rb.
Далее в нашей модели создаём константу HUMANIZED_ATTRIBUTES:
class User < ActiveRecord::Base
HUMANIZED_ATTRIBUTES = {
:login => "Имя пользователя"
}
validates_presence_of :login, :message => 'отсутствует'
end
И вуаля:

На самом деле это удобно не только для русифицирования атрибутов, но и когда заказчик хочет чтобы «login» отображался как «user name».
Для пущего удобства, можно обернуть всё это дело плугином с
redirect_to :back
Илья • 22 мая 2008 г.
Оказывается метод redirect_to может принимать аргумент :back.
def destroy
…
redirect_to :back
end
Теперь пользователь будет переброшен обратно на ту страницу, с которой пришёл запрос на destroy.
Очень полезно, когда действие может быть вызвано сразу с нескольких страниц и не понятно на какую из них пользователя перебрасывать.
Профилируем Rails-приложение
Илья • 8 апреля 2008 г.
В комплекте с каждым
Книга The Rails Way
Илья • 4 марта 2008 г.
Не так давно, в мире существовала всего одна книга по Ruby on Rails — Agile Web Development With Rails от создателя Rails Дэвида Хейнмейера Ханссона (David Heinemeier Hansson). Кто бы мог подумать, что сегодня у нас будет выбор из двадцати пяти книг на любой вкус и цвет! Ориентироваться в этом изобилии (ну ладно, пусть не изобилии, но многообразии) становится всё сложнее. Какую книгу выбрать? У меня есть подходящий ответ на этот вопрос…
На днях я купил
Книга достаточно толстая (900+ страниц) и выполнена в виде настольного руководства. В ней нет длинных уроков, домашних заданий и больших тестовых приложений. Она больше ориентируется на людей, которые способны самостоятельно изучить материал, имея максимально полную информацию об инструменте. Каждый компонент фреймворка подробно описан и сопровождён примерами. Иногда, автор приводит отрывки кода прямо из исходного кода Rails, чтобы разъяснить сложные моменты. Так же, практически в каждой главе можно найти актуальные советы по теме от профессиональных
Перечислять темы, которые затрагивает книга, можно бесконечно — одно только содержание занимает пятнадцать страниц. Радует наличие глав о таких, сравнительно новых для мира Rails, темах как REST, ресурсы и ActiveResource.
Книга хороша для более глубокого изучения компонентов фреймворка, а так же для поиска подробностей, не описанных (или описанных, но скудно) в официальной документации. Например раздел об ассоциациях ActiveRecord описывает прокси ассоциаций. А в разделе, посвящённому роутингу в Rails, детально описано как он устроен, с вставками исходного кода Rails.
Помимо описания самого фреймворка Rails, книга содержит множество информации о других подручных инструментах и технологиях, которые мы ежедневно используем в работе: Capistrano, Monit, Mongrel, Nginx, RSpec и даже весьма подробное изучение Prototype.js и Scriptaculous. Что это и как это установить? Как настроить лучшим образом и как использовать? На все эти вопросы книга даёт развёрнутые ответы. И это то, что делает The Rails Way таким хорошим кандидатом на покупку.
The Rails Way является практически идеальной заменой онлайн документации по Rails (за исключением медленного поиска) — в любой момент, когда у вас возник вопрос или хочется узнать как выполнить ту или иную задачу более правильным путём, она будет вашим лучшим помощником.
На мой взгляд, книга The Rails Way обязательно должна быть в библиотеке каждого
А что думаете вы?
Читаете ли вы техническую литературу на английском языке? Есть ли, по вашему мнению, смысл в русском переводе этой книги?
Дождались! Первая книга по Ruby on Rails на русском языке
Илья • 6 декабря 2007 г.
Издательство Питер
AWDWR это культовая книга, которая содержит в себе достаточно информации о рельсах, чтобы написать своё первое приложение с нуля. Просто незаменима для новичков и стажёров.
Уже сейчас книжку можно
Фильтровка списка доступных rake-задач
Илья • 22 ноября 2007 г.
Очень маленький, но весьма полезный трюк, который лично я открыл для себя только сегодня:
$ rake -T clear
(in /Users/ilya/work/application)
rake db:sessions:clear # Clear the sessions table
rake log:clear # Truncates all *.log files in log/ to zero bytes
rake tmp:cache:clear # Clears all files and directories in tmp/cache
rake tmp:clear # Clear session, cache, and socket files from tmp/
rake tmp:pids:clear # Clears all files in tmp/pids
rake tmp:sessions:clear # Clears all files in tmp/sessions
rake tmp:sockets:clear # Clears all files in tmp/sockets
То есть, после rake -T можно написать любое интересуемое вас слово, в данном случае clear. И тогда на экран выведутся только задачи в названии которых это слово встречается.
За открытие спасибо Антонюку Стасу ;)
Upd: Переписал описание и пример. Как оказалось позднее, выводятся не только задачи, у которых именная область совпадает с введённым словом, но и вообще все задачи, в название которых это слово включено.
Ruby on Rails теперь в комплекте с каждым Маком
Илья • 16 октября 2007 г.
Сегодня Apple назвала дату начала продаж новой версии операционной системы Mac OS 10.5 Leopard — 26 октября.
В Леопарде более 300 нововведений и улучшений. Наш любимый фреймворк не остался в стороне:
Да, Ruby on Rails, Ruby, Rubygems и Capistrano теперь идут в комплекте с каждым Маком. Ну разве это не здорово? ;)
Приятное обновление error_messages_for
Илья • 14 октября 2007 г.
В Edge Rails и Rails 2.0 теперь можно указывать допонительные параметры методу error messages for, который выводит ошибки валидации во вьюшках:
- :header_message По умолчанию: “<count> errors prohibited this <object_name> from being saved”
- :message По умолчанию: “There were problems with the following fields:"
<%= error_messages_for :user,
:header_message => "#{@user.errors.size} ошибок сохранения этого пользователя",
:message => "Следующие поля заполнены не верно:" %>
Так что теперь можно спокойно использовать эту удобную функцию в русских проектах.
Используем form_for с несколькими моделями
Илья • 5 октября 2007 г.
Не так давно в распоряжении
<% form_tag users_path do %>
<%= text_field :user, :name %>
<%= text_field :user, :email %>
<% end %>
в такой:
<% form_for :user, :url => users_path do |f| %>
<%= f.text_field, :name %>
<%= f.text_field, :email %>
<% end %>
Используя form_for, больше нету необходимости указывать более чем один раз кому принадлежит то или иное поле. Это уменьшает количество повторений в вашем коде, то есть делает его более DRY.
Но что делать, если вы хотите использовать сразу несколько моделей в рамках одной формы? В такой ситуации нам на помощь придёт метод fields for, который переопределяет объект, к которому будут принадлежать поля, находящиеся в его блоке.
Всё просто, давайте разберём следующий пример. В одной и той же форме мы хотим редактировать данные и пользователя, и его кредитной карты:
<% form_for :user, :url => users_path do |f| %>
<%= f.text_field, :name %>
<%= f.text_field, :email %>
<% fields_for :credit_card do |cf| %>
<%= cf.text_field :number %>
<%= cf.text_field :holder_name %>
<% end %>
<% end %>
Используя fields_for в примере выше, мы получили возможность описать сразу две модели в одной форме. Теперь в контроллере у нас доступны и params[:user] и params[:credit_card].
Эта тема так же подробно раскрывается в эпизоде 73 от Railscasts.
Разбиваем длинные выражения Ruby на несколько строк
Илья • 3 октября 2007 г.
Несколько компактных примеров о том, как можно разбивать длинные выражения в руби на несколько строк.
User.create! \
:name => 'Вася',
:password => '12345',
:login => 'vasya'
name = first_name +
last_name +
middle_name
name = "Sabanin" \
" Ilya" \
" Vladimirovich"
# name => "Sabanin Ilya Vladimirovich"
array.
find_all {|e| e.position > 5}.
map {|e| e.symbol}.
join('/').
downcase
Безопасность Rails: фильтрация логов
Илья • 25 сентября 2007 г.
Если в вашем приложении используются такие важные данные как номера кредитных карт или пользовательские пароли, то вам стоит фильтровать свои логи, в которые эта секретная информация просачивается.
Сделать это очень просто. Достаточно вставить следующую строку в ApplicationController:
class ApplicationController < ActionController::Base
filter_parameter_logging :password
end
В метод filter_parameter_logging через запятую передаются названия всех параметров, которые вы не хотите отображать в логах. Вы можете вызвать этот метод в любом контроллере, где должна совершаться фильтрация логов.
Важный нюанс: метод filter_parameter_logging использует регэкспы, для сравнения параметров, так что код, приведённый выше, будет работать для всех параметров, в названии которых содержится слово password.
Вот как выглядят логи с отфильтрованным параметром :password:
Processing AccountsController#login (for 127.0.0.1 at 2007-09-25 03:56:02) [POST]
Session ID: 66e0c98d03cc80433cecfe3cf76f65aa
Parameters: {"login"=>"vasya", "password"=> "[FILTERED]",
"password_confirmation"=> "[FILTERED]"}
Берегитесь операторов and, or и not в Ruby
Илья • 21 сентября 2007 г.
С виду безобидные операторы and, or и not могут привести к очень загадочным ошибкам в вашем приложении.
Вот две строчки одинакового кода. В первой строке используются операторы || и &&, а во второй операторы or и and. Как видите, результат не совпадает:
Всё
Что самое неприятное, операторы and и or стоят по приоритету даже ниже чем оператор =, а это может создать в коде ошибки следующего типа:
Такой же код, но с оператором || вместо or:
Теперь всё работает как надо.
Итак, старайтесь заменять операторы and, or и not на &&, || и !. Конечно, вторая тройка не такая красивая и читабельная, но читабельность того не стоит.



