Author Archive
Stránkování v Ruby on Rails – will_paginate + AJAX
by petrb on Oct.10, 2009, under Pluginy, Ruby on Rails
Mnoho lidí se ptá jak vytvořit stránkování pomocí AJAXu. I když se to nezdá je to velice jednoduché. Pokud nevíte jak se pracuje s pluginem will paginate, tak si přečtěte tento článek, budete to potřebovat :)
Nejdříve si musíme natáhnout v hlavičce potřebné soubory.
<%= javascript_include_tag :defaults, 'lowpro' %>
Jak už jste si všimli je potřeba stáhnout low pro knihovnu, kterou napsal Dan Webb. Toto rozšíření pro prototype lze stáhnout zde. Jakmile budete mít aktuální verzi, je potřeba ji nakopírovat do složky “public/javascript”. Poté si otevřete application.js z “public/javascript” složky a vložte do něj následující kód.
Event.addBehavior.reassignAfterAjax = true; Event.addBehavior({
'div.pagination a' : Remote.Link
})
Taktéž si můžete vytvořit jakýkoliv *.js soubor a vložit kód tam, ale pak je potřeba tento soubor z hlavičky zavolat spolu s lowpro.
Tak a teď máme nachystáno co budeme potřebovat a nyní jsme jen pár řádků od kýženého výsledku. V controlloreru si vybereme potřebná data a nastránkujeme pomocí will paginate, ale taky je potřeba zajistit odpověd na js request.
def index
@posts = Post.paginate(:all, :per_page => 10, :page => params[:page])
respond_to do |format|
format.html
format.js do
render :update do |page|
page.replace 'posts_box', :partial => [:posts];
end
end
end
end
Kód ve view (index.rhtml) by mohl vypadat následovně.
Nalezené články:
<%= render :partial => "posts" %>
------- #_posts.rhtml -------
<div id="post_box">
#zde vypiseme co chceme a nastránkujeme
<%= will_paginate(@posts) %>
</div>
Tak a to je všechno. :)
Petr Bobek
Stránkování v Ruby on Rails – Will_paginate
by petrb on Oct.05, 2009, under Pluginy, Ruby on Rails
Plugin si můžete stáhnout z následující adresy: http://github.com/mislav/will_paginate/
Na této adrese také naleznete základní informace o tom jak tento plugin využívat. Nějaké informace se dozvíte i tady :)
Aby nám plugin fungoval (rails > 2.1) je potřeba jej povolit v “config/enviroment.rb”
Rails::Initializer.run do |config|
config.gem 'mislav-will_paginate', :version => '~> 2.3.11', :lib => 'will_paginate', :source => 'http://gems.github.com'
end
Tento plugin a chybějící dependence NAINSTALUJEME když v konzoli napíšeme následující příkaz:
rake gems:install
a nebo druhou možností je manuální instalace pomocí následujících příkazů:
gem sources -a http://gems.github.com
gem install mislav-will_paginate
POUŽITÍ:
- @clanky = Post.find(:all, :order => 'datum DESC')
Výše uvedeným dotazem vypíšeme všechny články, které vyhovují podmínkám (takže všechny). Pokud bysme chtěli tyto články nastránkovat pomocí will paginate pluginu, provedeme jen malinkatou úpravu.
- @clanky = Post.paginate(:all, :order => 'datum DESC', :page => params[:page])
Jak jste si asi všimli místo find jsem použil paginate, ten funguje stejně jako find, ale jen s tím rozdílem, že nevytáhne z DB všechny záznamy. Nesmíme ale zapomenout na parametr page, bez něj skončíme s chybou. Takto se nám výsledky nastránkují po 30 záznamech (defaultní hodnota). Tu samozřejmě můžeme změnit, když nastavíme per_page parametr. Takže stránkování po 10 záznamech by mohlo vypadat následovně.
- @clanky = Post.paginate(:all, :order => 'datum DESC', :page => params[:page], :per_page => 10)
Tak a to je v controlleru vše a teď už jen potřebujeme vypsat články a taky naše stránkování.
- <ul> - <% @clanky.each do |clanek| %> - <li><%= clanek.titulek %></li> - <% end %> - </ul> - <%= will_paginate(@clanky) %>
Stačí když zavoláme funkci will_paginate s naší proměnou a máme pěkně nastránkováno. :)
ÚPRAVY:
Pravděpodobně budou všechny trápit i anglické názvy u tlačítek NEXT a PREVIOUS (další a předchozí). I na tohle, ale existuje velmi lehké a elegantní řešení. V souboru “config/enviroment.rb” přidáme následující řádky a po restartu by mělo být tak jak má :)
require 'will_paginate' WillPaginate::ViewHelpers.pagination_options[:previous_label] = 'Novější' WillPaginate::ViewHelpers.pagination_options[:next_label] = 'Starší'
Takto nastavíme všechny tlačítka v aplikaci (globálně všechny přepíšeme), ale existuje ještě jedna možnost, a to lokální. Pokud chceme změnit text jen u jednoho tlačítka, tak to můžeme udělat přímo a to tak, že přidáme další dva parametry :previous_label (pro předchozí tlačítko) a pak :next_label (pro tlačítko další). Vypadalo by to následovně.
@clanky = Post.paginate( ..... , :previous_label => 'Předchozí', :next_label => 'Další')
Pokud budete chtít smazat číslování, tak úprava je taktéž jednoduchá, přidáme jen :page_links a nastavíme jej na false.
Na závěr snad už jen doplním, že ve složce examples (link: http://github.com/mislav/will_paginate/blob/master/examples/index.html) se můžete podívat na nějaké CSS styly, tak to jen tak, kdyby se někomu nelíbilo standardní stylování.
V dalším pokračování si ukážeme stránkování pomocí AJAXu.
Nějaké dotazy, poznámky nebo připomínky?
Petr
Filtrování citlivých dat z logu
by petrb on Sep.05, 2009, under Bezpečnost
Vkládají uživatelé na Vašich stránkách citlivá data? Můžou to být hesla, čísla kreditních karet, atp. Pokud se např. uživatel loguje do systému, všechny jeho vložená data jsou uložena v log souboru, kde se uloží i např. hesla.
Tím, že do “controllers/application.rb” vložíte následující řádek:
filter_parameter_logging :heslo => tímto se heslo v log souboru nahradí za tento řetězec "[FILTERED]"
A to je vše. Velice jednoduchá a elegantní možnost jak citlivá data z log souborů filtrovat.
Hrajeme si s CACHE v Ruby on Rails
by petrb on Aug.04, 2009, under Optimalizace, Ruby on Rails, cache
CO JE TO CACHE (keš)?
Keš jako takovou si můžeme představit jako složku se statickými html soubory, které byly po prvním načtení stránek vygenerovány. Jakmile někdo druhý bude chtít zobrazit stejnou stránku, tak už nebudou posílány dotazy na server, ale stránka bude vytažena z keše. Tím se zaprvé sníží vytížení serveru a za druhé načtení stránky bude taky nesrovnatelně rychlejší. Soubory jsou ukládány do tmp složky ve vaší aplikaci.
KONFIGURACE
Proto aby jste si mohli začít hrát s keší, není potřeba vůbec nic složitého. Je potřeba, nastavit v config/environments/development.rb
config.action_controller.perform_caching = true
Defaultně je tato možnost nastavena na false, protože při vývoji aplikace se tato možnost nepokládá za prospěšnou. :) V production módu není nic potřeba nastavovat, je to tam již nastaveno.
POTŘEBUJI CACHE?
Používání keše se doporučuje všude tam kde je to jen možné v co možná největší míře. Níže uvádím příklady kdy je kešování vhodné.
- stránky se nemění (resp. jsou pro všechny uživ. stejné)
- stránky jsou dostupné pro veřejnost (není potřeba autentifikace)
Druhá podmínka je podstatná, ale i ta se dá obejít použití javascriptu, ale na druhou stranu se zase snižuje přístupnost webu, protože přihlášení uživ. je podmíněno zaplým javascriptem. V tomto článku se ale tomuto tématu věnovat nebudeme. (Někdy přístě můžeme nakousnout i toto téma)
PAGE CACHE
Představme si, že vytváříme jednoduchou aplikaci (např. knihovna). Úvodní stránka může vypadat nějak následovně.
- class BooksController < ApplicationController - def index - @knihy = Book.find(:all, :order => "created_at DESC", :limit => 10) - end - end
Na indexové stránce se nám vybere 10 nejaktuálnějších knih. Pokud budeme chtít trošku věci urychlit, tak můžeme použít page kešing. Na začátek controlleru jen specifikujeme, který action blok budeme chtít kešovat, pomocí direktivy “caches_page”.
- class BooksController < ApplicationController - caches_page :index - def index - @knihy = Book.find(:all, :order => "created_at DESC", :limit => 10) - end - end
Tak a teď se nám podařilo zdárně zakešovat indexovou stránku. Další krok, který bude následovat je smazání vytvořené keše (resp. zrušíme platnost keše). Keš budeme chtít smazat když přidáme např. nový článek, nebo když stávající editujeme. Kdyby jsme keš nesmazali, tak by se nám změny na úvodní stránce neprojevily a stále by se nám načítal starý zakešovaný obsah.
- expire_page(:controller => ‘books’, :action => ‘index’)
Problém může nastat, pokud bysme zakešovali specifickou stránku např. “/books/show/15″ a pak chtěli zrušit tuto keš. Řešením je použití :id, kde specifikujeme o jaký článek se bude jednat. :)
- expire_page(:controller => ‘books’, :action => ‘show’, :id => 15)
Další možností jak vymazat cache je použití tzv. sweeper-ů. Použití je taktéž velmi intuitivní a jednoduché. Nesmíme však opomenout daný sweeper v controlleru specifikovat.
- class BooksController < ApplicationController - caches_page :index - #sweeper budeme aplikovat jen na následující metody - cache_sweeper :book_sweeper, :only => [:create, :update, :destroy] - def index - @knihy = Book.find(:all, :order => "created_at DESC") - end - end
vytvoříme book_sweeper.rb, který umístíme do naší “/model” složky.
- class BookSweeper < ActionController::Caching:Sweeper - #zde definujeme, který model chceme pozorovat - observe Book - def after_create(record) - expire_page(:controller => "books", :action => "show", :id => "15") - end - def after_update(record) - ... - end - def after_destroy(record) - ... - end - end
V další části se podíváme na action cache a fragment cache. ;)
Dotazy, poznámky, připomínky jsou vítány.
Petr Bobek