Ruby on Rails

Ruby on Rails

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

3 komentářů :, , , více zde...

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

Vlož komentář :, , , více zde...

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.

Vlož komentář :, více zde...

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

Vlož komentář :, , více zde...

Nemůžete něco najít?

Použijte formulář a zkuste štěstí:

Stále nenacházíte co jste hledali? Zkuste nechat komentář u článku!

Oblíbené blogy!

Archiv

Všechny články, chronologicky...