Pull to refresh

Обзор новинок в Ruby on Rails

Reading time 5 min
Views 1.8K
Для начала мы обратим внимание на Rails 2.3.8 — многие из вас слышали о нем, но не все знают, что конкретного там поменялось. К слову, основные нововведения произошли в версии 2.3.6, а .7 и .8 версии лишь исправляли ошибки.

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

1. Переработан флеш, рекомендуется использовать два базовых типа — alert и notice. А еще его можно использовать с редиректом.
Вот как было:
flash[:notice] = 'Статья добавлена'
redirect_to @article
И как можно писать теперь:
redirect_to(@article, :notice => 'Статья добавлена')
Стоит учесть, что если у вас есть свой тип флеша, например, flash[:error], то добавить его к редиректу не получится.

2. Для пользователей базы MySQL добавлена пара очень полезных нововведений:
 — Теперь можно указывать длину индекса:
add_index(:accounts, :name, :name => 'by_name', :length => 10)
# => CREATE INDEX by_name ON accounts(name(10))
 
add_index(:accounts, [:name, :surname], :name => 'by_name_surname', :length =>
 {:name => 10, :surname => 15})
# => CREATE INDEX by_name_surname ON accounts(name(10), surname(15))

 — Методы add_ и change_column теперь поддерживают параметр :first => true, и :after => :column. Раньше оно добавляло новые колонки в конец таблицы, а теперь можно явно указать куда их ставить:
add_column :comments, :post_id, :integer, :first => true

3. Если вы используете тестирование с помощью стандартных тестов рельсов, то вам могут помочь новые методы assert_blank and assert_present. Первый сравнивает объект с пустой строкой, а второй проверяет его наличие.

4. Добавлена функция объекта Object#presence, которая возвращает сам объект, если он существует и не является пустой строкой, в ином случае возвращает nil. И это очень удобно для выбора одного из различных параметров (любители синтаксического сахара ликуют):
region = params[:state].presence || params[:country].presence || 'US'

5. К типу Enumerable добавлен метод exclude?, который является противополножностью метода include?, и возвращает true, если указанный объект не содержит элемента 
array = ['foo', 'bar']
array.exclude?('boo')  # => true
array.exclude?('bar')  # => false

Также не стоит упускать из внимания несколько интересных гемов.

Sentient User [link]


Назначение его довольно простое — он позволяет использовать current_user в моделях. Кто-то скажет, что в моделях не стоит мешать методы контроллеров, но лично мне этот гем был очень полезен, когда я прописывал различные валидации. Использовать его очень просто — достаточно прописать «include SentientController» в вашем ApplicationController'e. Не стоит забывать, что если ваш модуль авторизации не поддерживает метод current_user, то вам стоит создать его самостоятельно. На таких популярных механизмах как Restful Authentication и Authlogic проблем быть не должно.

Request Rate Limiter [link]


Если ваше приложение уже не такое маленькое как раньше, и количество пользователей постоянно растет — вы должны подумать о безопасности. Этот плагин позволит защититься от слишком частых запросов, которые могут сделать не очень доброжелательные юзеры (или возможные конкуренты). Использовать не сложнее, чем предыдущий:
# config/application.rb
require 'rack/throttle'

class Application < Rails::Application
  config.middleware.use Rack::Throttle::Interval
end

Затем прописываем ограничения на запросы:
use Rack::Throttle::Daily,    :max => 1000  # количество запросов за день
use Rack::Throttle::Hourly,   :max => 100   # количество запросов за час
use Rack::Throttle::Interval, :min => 3.0   # минимальный интервал между запросами

Также можно указать, какое хранилище использовать — поддерживаются GDBM, Memcached и Redis.
Однако доступен этот плагин лишь в Rails 3.0+, так что актуален он будет лишь в будущем, или если вы разрабатываете приложение на бета-версии рельсов.

CanCan [link]


Это замечательный способ ограничения прав юзеров на вашем сайте.
Первое, что нам надо сделать, это создать класс ability, который мы сохраним в models/ability.rb
  class Ability
    include CanCan::Ability

    def initialize(user)
      if user.admin?
        can :manage, :all
      else
        can :read, :all
      end
    end
  end

Именно там будут храниться все разрешения.
Затем, можно использовать это во view:
  <% if can? :update, @article %>
    <%= link_to "Edit", edit_article_path(@article) %>
  <% end %>

В контроллере можно использовать метод authorize!, который вызовет исключение, если у юзера не будет прав на действие:
  def show
    @article = Article.find(params[:id])
    authorize! :read, @article
  end

Исключение можно перехватить и обработать, в нашем случае мы уведомляем юзера об отсутствии доступа с помощью флеша и редиректа:
  class ApplicationController < ActionController::Base
    rescue_from CanCan::AccessDenied do |exception|
      # примечание - лучше использовать redirect_to(root_url, :alert => exception.message)
      flash[:error] = exception.message
      redirect_to root_url
    end
  end

Как вы видите — никаких сложностей тут не возникает, и не стоит изобретать велосипед, когда всё хорошее уже придумано за вас.

Использованы материалы с документации описанных плагинов, а сами плагины были найдены на сайте Riding Rails
Tags:
Hubs:
+48
Comments 26
Comments Comments 26

Articles