Валидация форм без создания модели

Posted on March 21, 2007
Иногда требуется провалидировать форму без создания для неё модели.
Для этой цели существует плагин
Создаём в моделях файл псевдомодели например:

class Msg < ActiveRecord::BaseWithoutTable
  column :subject, :string
  column :from, :string
  column :message, :string
  validates_presence_of :subject,:message
  validates_format_of :from, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
  validates_length_of :from, :within => 5..255
end
а в контроллере её используем как модель.

Всё гениальное просто!

Кеширование отдельных фрагментов страницы.

Posted on March 21, 2007
Кэширование целых страниц это конечно хорошо, но иногда - абсолютно бесполезная вещь.
Для этих целей необходимо применять кэширование отдельных фрагментов.
Например, у нас есть контроллер выдающий список пользователей

class UserController < ApplicationController
  layout 'main'

  def list
    @users = User.find :all
  end
  def show
    @user = User.find params[:id].to_i
  end
end
Для кэширования этих экшенов необходимо немного переработать данный код

class UserController < ApplicationController
  layout 'main'
  caches_action :list, :show

  def list
    unless read_fragment({})
      @users = User.find :all
    end
  end
  def show
    unless read_fragment({:id => params[:id].to_i})
      @user = User.find params[:id].to_i
    end
  end
end
В шаблоне же необходимо блок которй будщет кэшироваться заключить в следующую конструкцию:

<% cache do %>

<%end %>
Для удаления кэшированного фрагмента используется комманда expire_fragment. Например

expire_fragment(:controller => 'user', :action => 'list')
expire_fragment(:controller => 'user', :action => 'show', :id => 3)
При необходимости можно перенести директорию в которой находится кэш с помощью вписывания в environment.rb следующей строки:

ActionController::Base.fragment_cache_store = :file_store, "/path/to/cache/directory"


Более подробно это описано тут

Краткое описание RubyInline

Posted on March 20, 2007
Руби конечно быстрый язык, но иногда необходимо производить вычисления ещё быстрее
Для этого существует пакет RubyInline он предназначен для включения в код на руби небольших отрезков на C. Для примера рассмотрим простейшую задачу - поиск факториала.

class Test
  def factorial(n)
    f = 1
    n.downto(2) { |x| f *= x }
    f
  end
end

t = Test.new
tstart = Time.now
t.factorial(200)
tend = Time.now
puts tend - tstart
Теперь рассмотрим код такого-же функционала но с RubyInline

require 'rubygems'
require 'inline'
class Test
   inline do |builder|
     builder.c "
     long factorial(int max) {
     int i=max, result=1;
     while (i >= 2) { result *= i--; }
      return result;
    }"
  end
end

t = Test.new
tstart = Time.now
t.factorial(200)
tend = Time.now
puts tend - tstart
И сравним время, у меня в тесте №1 время получилось равным: 0.001903
А в тесте номер №2 - 0.0000032
Так что результат на лицо ).

P.S. Под windows b системы без компилятора работать не будет.
P.P.S Под Windows используйте cygwin или просто переходите на другую OS

Небольшой хак на auto_admin для закачки файлов через file_column

Posted on March 12, 2007
В автоадмине не реализовано много вещей, что не радует.
Одной из этих вещей является поддержка закачки файлов.
Но это можно исправить, заменив в lib/auto_admin_simple_theme.rb

    def file_field(field, options = {})
    end
на

    def file_field(field, options = {})
      common_option_translations! options
      super
    end
Хак конечно не идеален, но на первое время сойдёт. В дальнейшем я более качественно покопаюсь в этом и напишу патч.

Генерация pdf на ruby

Posted on March 05, 2007
Довольно часто возникает необходимость оформить отчёт в виде какого-либо файла, а не как просто html.
Для этих целей замечательно подходит PDF.

Небольшой обзор по кешированию страниц

Posted on March 05, 2007
В Rails есть очень хороший механизм кеширования страниц.
Для начала, естественно его надо включить дописав следующую строку в environment.rb:

config.action_controller.perform_caching = true
После этого можно начинать кешировать страницы. Делается это так: допустим имеется контроллер Article:

class ArticlesController < ApplicationController
  def get
   @article = Article.find params[:id]
  end
end
Путём добавки следующего кода в контроллер мы получим контроллер который кеширует содержимое

class ArticlesController < ApplicationController
  caches_page :get
  def get
   @article = Article.find params[:id]
  end
end
При первом запросе будет сгенерирована страница и положена в кеш.
Для управления кешированием используется функция

expire_page(:controller => 'article', :action => 'get', :id => 5)
Таким образом можно не особо заморачиваясь работать с кешированием страниц
В статье Расписано более подробно как автоматиз-ировать кеширование, и некоторые другие особенности

Небольшой хинт о создании своих типов данных для ActionWebService

Posted on March 04, 2007
Всё очень просто, создаём директорию app/structs и добавляем в environment.rb этот путь для подгрузки. Теперь, допустим у нас есть сервис Article примерно такого вида(article_api):

class ArticleApi < ActionWebService::API::Base
  api_method :get_article, :expects => [:int], :returns => [Article]
  api_method :list_articles, :returns => [[ArticleStructs::ArticleShort]]
end
Теперь создаём файлик app/structs/article_structs.rb в который пишем следующее:

module ArticleStructs
  class ArticleShort < ActionWebService::Struct
    member :id, :integer
    member :header, :string
  end
end
Всё, теперь в контроллере на выдачу мы можем составлять массив из переменных типа ArticleShort