Маленький Безобидный Трюк
Дима • 13 мая 2007 г.
Если хочется чтобы
@group = Group.find(params[:group_id])
не вызывало исключения в случае если группа не найдена, то можно сделать так:
@group = Group.find_by_id(params[:group_id])
Мне кажется что во многих случаях это явно лучше чем rescue nil.
Регэкспы для валидаций
Илья • 3 мая 2007 г.
Каждый раз пишу валидации и каждый раз приходится искать в инете регэкспы или писать самому (ну нет…). Спасибо Рику Олсену за наше счастливое детство — теперь для меня эта проблема навсегда снята.
Я откопал в его Мефисто маленький файлик format.rb, в котором описаны все, нужные для валидаций, регэкспы. Теперь этот файлик кочует из одного моего проекта в другой.
Итак, копируем файл в папку lib/ и используем его во время написания валидаций:
Ляпота? :)
Грамотные сообщения об ошибках валидации
Илья • 29 апреля 2007 г.
Представим что у нас есть модель User со следующими валидациями:
class User < ActiveRecord::Base
validates_presence_of :username
validates_presence_of :email
validates_presence_of :password
validates_length_of :password, :in => 6..12
attr_accessor :password
end
Самая обычная модель с самыми обычными валидациями. Вот только, если мы не заполним поле пароль, у нас сработают сразу две ошибки: пароль не может быть пустым и пароль слишком короткий. Абсурд: конечно пароль короткий, ведь его нет!
Решается всё элементарно: добавляем флаг :allow_nil => :true для валидации длины пароля:
class User < ActiveRecord::Base
validates_presence_of :username
validates_presence_of :email
validates_presence_of :password
validates_length_of :password, :in => 6..12, :allow_nil => true
attr_accessor :password
end
Теперь, если пользователь не введёт пароль, то сработает только валидация присутствия, а валидация на длину будет молчать как партизан.
Просто приятная мелочь, которая позволит сделать ваши сообщения об ошибках менее загруженными и абсурдными.
Update: Поправка опечатки.
Belongs_to :counter_cache
Илья • 24 апреля 2007 г.
Как всё-таки иногда полезно почитать чужой код. Особенно, если его писал Рик Олсен ;)
Ковыряясь в Beast, наткнулся на интересную штуку, которую раньше не замечал:
class Topic < ActiveRecord::Base
belongs_to :forum, :counter_cache => true
…
Флаг counter_cache сделан для автоматического сохранения в базе количество ассоциированных объектов. Будет их автоматически наращивать и уменьшать при добавлении и удалении соответственно.
Для того чтобы вся эта красота работала, в таблице бд модели нужно добавить поле с именем типа «#{table_name}_count». Или, если вы хотите собственное название, достаточно просто его прописать вместо true:
class Topic < ActiveRecord::Base
belongs_to :forum, :counter_cache => :super_puper_counter
…
Делается это всё для быстроты. Чтобы каждый раз, когда вам нужно узнать сколько у форумов топиков (к примеру), вам не нужно было бы делать SQL-запрос, считая все топики.
Как приятно узнать что-то новое.
Update: добавил информацию о том, как нужно назвать поле в базе данных
Simple Emptiness
Дима • 31 марта 2007 г.
На днях мне пришла в голову идея которая показалась мне интересной.
Для строк:
"" | "default" # "default"
" \n" | "default" # "default"
" blah " | "default" # " blah "
Для хешей:
{} | {:default => :value} # {:default => :value}
Для других объектов:
false | "something" # "something"
nil | "something" # "something"
true | false # true
{:pi => 3.1416} | {:pi => 3.14159265} # {:pi => 3.1416}
Для массивов работать не будет, у них уже есть метод |, который объединяет два массива удаляя дубликаты.
Также, ещё один недостаток это то, что данный способ не предполагает lazy evaluation, то есть следующий код вызовет и some_method() и redundant_method() при любом условии:
value = some_method() | redundant_method()
А вообще, всё это было сделано для того, чтобы сократить количество строк при следующем действии:
@plan = params[:plan_name].to_s.strip.empty? ? "Not given." : params[:plan_name]
До:
@plan = params[:plan_name] | "Not given."
Ну а потенциально может пригодиться и в множестве других случаев.
Скачать файл с кодом можно здесь: simple_emptiness.rb
У кого есть предложения по поводу того как это можно ещё использовать или улучшить?
Update: по поводу замечания насчет возможного использования метода blank? (из ActiveSupport) вместо цепочки to_s.strip отмечу, что код писался с расчетом на возможное использование и в pure ruby проектах, поэтому решено было зависимости сократить по минимуму.
Что нового в рейлс: ручное подключение хелперов
Илья • 22 марта 2007 г.
Вместо того, чтобы забивать ApplicationHelper сотнями различных методов, только для того, чтобы они были доступны во всех “вьюшках”, лучше создайте несколько отдельных хелперов и вынесите туда часть методов. Так вы упорядочите свой код, сделаете его более читабельным и удобным.
А подключить эти хелперы в своё приложение можно вот так:
class ApplicationController < ActionController::Base
helper "javascript" # Подключаем JavascriptHelper
helper "images" # Подключаем ImagesHelper
end
Или, если вы используете edge Rails, то вот так:
class ApplicationController < ActionController::Base
helper :all # Подключаем абсолютно все хелперы из папки app/helpers
end
Кстати, второй вариант теперь стандартный для всех новых edge Rails приложений.
Совет для маководов
Илья • 9 марта 2007 г.
Обалденный совет, позволяющий отключить функцию Safe Sleep у Мака и тем самым сократить время ухода в режим сна в несколько раз.
Прикол в том, что каждый раз когда вы “усыпляете” Мак, он копирует всё содержимое оперативной памяти в файл, чтобы если у вас вдруг во время сна кончилась батарейка, то он мог спокойно выключиться, а потом, когда вы подключите его к сети и нажмёте кнопку ВКЛ, быстренько восстановить содержимое оперативки из этого файла. Это и называется режим Safe Sleep, то есть когда содержимое оперативной памяти сохраняется на винт.
На деле, у меня лично не было ни разу случая, когда садилась бы батарейка и мак был вынужден уходить в Safe Sleep. Более того, даже если это случится и у меня режим Safe Sleep будет выключен (как сейчас), то пусть у меня всё сбросится — мне не страшно загрузить всё заново. Зато каждодневное использование Мака стало гораздо более приятней, потому что засыпает он теперь за три секунды, вместо привычных 10-20. И ещё 2 гига на винте сэкономил, что всегда приятно :)
Новое в рейлс: аннотации кода
Илья • 27 февраля 2007 г.
Новенькая фишка в edge rails. Теперь в коде можно расставлять маленькие заметочки для себя, а потом удобно вывести их все на экран, используя rake.
Например в коде у нас вот что:class Friendship < ActiveRecord::Base
# TODO: Ability to make friends with your eyes closed.
def make_friends
#code here
end
# FIXME: Right now if your friend is Britney you just can't lose her...
def lose_friends
#code here
end
# OPTIMIZE: Contact Hannibal to optimize this method
def eat_friend
#code here
end
end
А потом запускаем rake notes и получаем список всех заметок со всего приложения:
$ rake notes
app/models/friendship.rb:
* [3] [TODO] Ability to make friends with your eyes closed.
* [8] [FIXME] Right now if your friend is Britney you just can't lose her...
* [13] [OPTIMIZE] Contact Hannibal to optimize this method
Баш скрипт для быстрого создания rails-приложений
Илья • 8 февраля 2007 г.
Наткнулся на очень удобный баш скрипт (для мак ос и юниксов, разумеется), который делает вот что:
- Создаёт чистое рельсовое приложение.
- Импортирует его в свн репозитарий.
- Удаляет и ставит игнор на логи, кэш, сессии и прочее в папке tmp.
- Копирует database.yml в database.example и ставит на него игнор.
Очень удобно! Качать тут.
Инструкции для жизни от Далай Ламы
Дима • 7 февраля 2007 г.
- Учитывай что великая любовь и великие достижения требуют великого риска.
- Когда проиграл, вынеси из этого урок.
- Уважай себя, уважай других и неси ответственность за все свои действия.
- Помни, что иногда не получить то, что хочешь, это удивительный подарок судьбы.
- Знай правила, чтобы правильно их нарушать.
- Не давай маленькой ссоре разрушить великую дружбу.
- Когда понимаешь что сделал ошибку, не медли ни секунды чтобы её исправить.
- Проводи немного времени наедине с собой каждый день.
- Будь открыт для изменений, но не отпускай свои ценности.
- Помни, что иногда тишина—это лучший ответ.
- Веди добрую, достойную жизнь. Тогда в старости, когда оглянешься назад, ты сможешь насладиться ей ещё раз.
- Любящая атмосфера в твоём доме это фундамент для твоей жизни.
- В разногласиях с теми кого любишь, смотри только на текущую ситуацию. Не поднимай то, что было в прошлом.
- Делись своим знанием. Это путь к достижению бессмертия.
- Будь вежлив с Землей.
- Раз в год, бывай там где никогда раньше небыл.
- Помни, что лучшие отношения те, в которых ваша любовь друг к другу превосходит вашу потребность друг в друге.
- Оценивай свой успех по тому, что тебе пришлось отдать чтобы его получить.
- Относись к любви и приготовлению пищи с безудержной энергией.
Updated: Пермалинк на этот пост был сломанный. Теперь всё работает.
Ошибка после обновления ruby gems до 0.9.x
Илья • 7 февраля 2007 г.
В связи с выходом новых рельс, нужно было обновить ruby gems до версии 0.9.x.
После обновления гемов, при попытке установить новые рельсы, вылетела ошибка:
ERROR: While executing gem ... (NoMethodError)
undefined method `refresh' for #<Hash:0x14fbfd0>
Ошибка проявляется как на Мак ОС, так и на линуксе и даже солярисе.
Решается очень просто: стираем файл source_cache в системной папке ruby/gems/1.8
Updated: ребята с Riding Rails уже написали об этой проблеме.
Используем Локомотив как стандартный Руби
Илья • 30 января 2007 г.
Тем, кто пользуется Mac OS и Locomotive посвящается этот небольшой трюк.
С помощью нехитрой ловкости рук, можно прописать весь environment локомотива подгружаться каждый раз, когда вы включаете терминал.
Это очень удобно, если у вас в системе нету ни Руби, ни рельсов, зато они есть под локомотивом. Вы и не заметите разницу: просто включаете терминал и вот у вас и руби и рельсы и все гемы с рмагиком :)
Собственно вот здесь прекрасно описано как это сделать.
Единственное замечание, я в .locomotive.environment.bash в конце ещё clear добавил, чтобы консоль не заспамливать.
Используем символ как Proc
Илья • 29 января 2007 г.
Просто замечательный пример элегантности Руби:
Вместо:@people.collect{|human| human.name }
Делаем так:
@people.collect(&:name)
Dave Thomas подробно описал как это работает.
Ловим exception внутри выражений
Илья • 28 января 2007 г.
Век живи, век учись.
Не так:if @user.name
@user.name.capitalize
else
"name not set"
end
И не так:
@user.name? ? @user.name.capitalize : "name not set"
И даже не так:
begin
@user.name.capitalize
rescue
"name not set"
end
А вот так:
@user.name.capitalize rescue "name not set"
Красота…
Update: Привёл немного не подходящий пример в прошлый раз: @user.name обычно не возвращает исключение, поэтому этот метод тут не поможет.
Another update: На самом деле этот хак не стоит воспринимать слишком серьёзно. Есть большая вероятность того, что вы не поймаете какое-нибудь действительно важное исключение, которого вы не ожидали.
Наблюдаем за ActiveRecord
Илья • 26 января 2007 г.
Небольшая, но приятная находка, которая позволяет следить за тем что делает ActiveRecord прямо из script/console.
$ script/console
>> ActiveRecord::Base.logger = Logger.new(STDOUT)
=> #<Logger:0x2814134 ...>
>> user = User.find :first
User Load (0.000346) SELECT * FROM users LIMIT 1
=> #<User:0x2665478 ...>
По-поему очень удобно.
