Ajax Russia : Аякс по-русски

Свежие новости из мира IT

5 советов по Ruby on Rails

English version

Ryan Bates с railscasts.com проводит конкурс. Нужно написать 5 советов по Ruby on Rails. Это могут быть советы по производительности, работе с sql, плагинами и тд. Вообщем всё что связано с разработкой сайтов на Ruby on Rails. Я тоже решил поучаствовать.

  1. Включить Logger в консоле
    Часто бывает нужно протестировать какие нибудь объекты и их поиск в базе данных в консоле. Только вот SQL запрос который отправляется на сервер не видно. Не беда! Создадим файл log_to.rb в config\initializers\

    RUBY:
    1. def log_to(stream)
    2.   ActiveRecord::Base.logger = Logger.new(stream)
    3.   ActiveRecord::Base.clear_active_connections!
    4. end

    Теперь в консоли достаточно написать

    RUBY:
    1. log_to SDTOUT

    и все SQL запросы будут видны.

  2. Форматирование дат
    Rails позволяет делать такие фокусы:

    RUBY:
    1. User.find(:first).created_at.to_s(:db)
    2. => "2008-01-23 21:44:03"

    А что если нужен какой то свой формат для дат? Например я хочу показать только время. Сделаем файл date_formats.rb в config\initializers\

    RUBY:
    1. ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.merge!(:time => '%H:%M')

    Мы сделали свой формат :time. Теперь можно писать следующее

    RUBY:
    1. User.find(:first).created_at.to_s(:time)
    2. => "21:44"

  3. Как создать объект по умолчанию
    Например у нас есть 2 модели. User и UserInfo

    RUBY:
    1. class User <ActiveRecord::Base
    2.   has_one :user_info
    3. end
    4.  
    5. class UserInfo <ActiveRecord::Base
    6.   belongs_to :user
    7. end

    Мы хотим создать юзера и одновременно его данные, например адрес. Раньше у нас было бы что то подобное в контроллере.

    RUBY:
    1. def new
    2.   @user = User.new
    3.   @user.build_user_info
    4. end

    Если не сделать @user.build_user_info, то будет Nil Exception во View. Мне кажется эту вторую строку можно убрать в модель.

    RUBY:
    1. class User <ActiveRecord::Base
    2.   has_one :user_info
    3.  
    4.   alias_method :user_info_original, :user_info
    5.  
    6.   def user_info
    7.     self.user_info_original || self.build_user_info
    8.   end
    9. end

    Теперь если у юзера уже есть user_info, то ничего не изменится. Если же нету, то будет сделан новый объект UserInfo и присвоен юзеру.

  4. Поиск BETWEEN
    Допустим нам надо найти всех юзеров, которые зарегистрировались в последние 5 дней. Это можно сделать например так:

    RUBY:
    1. User.find :all, :conditions => ["created_at BETWEEN ? AND ?", 5.days.ago, Time.now]
    2. # SELECT * FROM `users` WHERE (created_at BETWEEN '2008-04-07 20:05:41' AND '2008-04-12 20:05:41')

    Но можно и написать тоже самое поэлегантнее. Rails умеет конвертировать Date range в SQL.

    RUBY:
    1. User.find :all, :conditions => {:created_at => 5.days.ago..Time.now}
    2. # SELECT * FROM `users` WHERE (`users`.`created_at` BETWEEN '2008-04-07 20:06:04' AND '2008-04-12 20:06:04')

  5. Как найти медленные SQL запросы и их оптимизация
    Я использую для этого плагин query_reviewer. Он показывает какие sql запросы нужно оптимизировать, пишет причины и в каком месте они были запущены.
    Установка:

    RUBY:
    1. svn export http://query-reviewer.googlecode.com/svn/trunk/ vendor/plugins/query_reviewer

    Теперь откройте свой сайт в браузере и в левом верхнем углу будет инфо-диалог от query_reviewer.
    query_reviewer.png

Надеюсь кому то мои советы пригодятся. Если хотите поучаствовать в конкурсе, то напишите свои 5 советов, опубликуйте в своём блоге или на форуме railsforum.com и отправьте линк на contest@railscasts.com

Призы очень хорошие, так что постарайтесь ;)

Дальше то же самое на английском.


My 5 Ruby on Rails tips. Hope you find them useful.

  1. Logging to console
    Often you want to test your models in the console and look at the the sql queries your finder methods generate. But there's a problem - the console won't show you the sql queries. Let's fix this. Create a file log_to.rb in config\initializers\

    RUBY:
    1. def log_to(stream)
    2.   ActiveRecord::Base.logger = Logger.new(stream)
    3.   ActiveRecord::Base.clear_active_connections!
    4. end

    Now you can write this in the console

    RUBY:
    1. log_to SDTOUT

    and all your sql queries will be logged to console.

  2. Custom date formatting
    Rails lets you do things like:

    RUBY:
    1. User.find(:first).created_at.to_s(:db)
    2. => "2008-01-23 21:44:03"

    But what if I need my own custom date format? For example I want to show just the time. That's easy. Create a file date_formats.rb in config\initializers\

    RUBY:
    1. ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.merge!(:time => '%H:%M')

    We just created a custom :time format. Now we can write things like this:

    RUBY:
    1. User.find(:first).created_at.to_s(:time)
    2. => "21:44"

  3. Create associated objects
    For example we have 2 models. User and UserInfo

    RUBY:
    1. class User <ActiveRecord::Base
    2.   has_one :user_info
    3. end
    4.  
    5. class UserInfo <ActiveRecord::Base
    6.   belongs_to :user
    7. end

    We want to create a form for a new user. But there we also want to edit the associated UserInfo model. Previously we would end up with something like this in the controller.

    RUBY:
    1. def new
    2.   @user = User.new
    3.   @user.build_user_info
    4. end

    If you don't do the @user.build_user_info part, you'll probably end up with a Nil Exception in the view. I think we can move this line to the model

    RUBY:
    1. class User <ActiveRecord::Base
    2.   has_one :user_info
    3.  
    4.   alias_method :user_info_original, :user_info
    5.  
    6.   def user_info
    7.     self.user_info_original || self.build_user_info
    8.   end
    9. end

    Now if a User already has a user_info, it will just be returned. If not, a new UserInfo will be created and assigned to the user.

  4. Find BETWEEN
    Let's say we want to find all users registered in the last 5 days. You could do it like this:

    RUBY:
    1. User.find :all, :conditions => ["created_at BETWEEN ? AND ?", 5.days.ago, Time.now]
    2. # SELECT * FROM `users` WHERE (created_at BETWEEN '2008-04-07 20:05:41' AND '2008-04-12 20:05:41')

    But you can write it a bit more elegant. Rails can convert Date ranges to SQL.

    RUBY:
    1. User.find :all, :conditions => {:created_at => 5.days.ago..Time.now}
    2. # SELECT * FROM `users` WHERE (`users`.`created_at` BETWEEN '2008-04-07 20:06:04' AND '2008-04-12 20:06:04')

  5. How to find slow queries and optimize them
    I use a plugni called query_reviewer for that. It shows you sql queries that you need tom optimize, reasons why and it even shows you where they were executed.
    Install:

    RUBY:
    1. svn export http://query-reviewer.googlecode.com/svn/trunk/ vendor/plugins/query_reviewer

    Now open your site in the browser and in the top left corner you'll see the query_reviewer dialog.
    query_reviewer.png

del.icio.us Забобрить!

No comments yet. Be the first.

Leave a reply