Archív pro rubriku “Ruby on Rails”
Pokud chcete automaticky mít zobrazená všechna data v českém formátu, tak ideální DRY postup je přidat do config/environment.rb řádky (první pro datum, druhý pro čas):
ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS[:default] = '%d.%m.%Y'
ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS[:default] = '%d.%m.%Y %H:%M'
Jenže ouha, tohle vám rozbije zpětnou konverzi dat od uživatele – Rails ve verzi 2.1 totiž dají přednost formátu mm.dd.yyyy před dd.mm.yyyy (08.01.2008 tedy uloží jako 1. srpen 2008) a nenašel jsem žádnou možnost tohle chování změnit. Pokud chcete všechno provést bez použití pluginů, tak můžete předefinovat metody string_to_date a string_to_time v ActiveRecord, které se starají o konverzi textových řetězců na objekty Date resp. DateTime. Vytvořte soubor config/initializers/active_record.rb a vložte do něj:
module ActiveRecord
module ConnectionAdapters
class Column
def self.string_to_date_with_european_format(string)
begin
Date.strptime(string, '%d.%m.%Y')
rescue
string_to_date_without_european_format(string)
end
end
def self.string_to_time_with_european_format(string)
begin
DateTime.strptime(string, '%d.%m.%Y %H:%M')
rescue
string_to_time_without_european_format(string)
end
end
class << self
alias_method_chain :string_to_date, :european_format
alias_method_chain :string_to_time, :european_format
end
end
end
end
Restartujte webserver a hotovo. Předefinované metody se v případě neúspěchu s konverzí pokusí zavolat svojí původní verzi, takže se nemusíte bát, že by přestaly fungovat konverze z oblíbených formátů yyyy-mm-dd a jiných.
Bez komentářů »
Možná jste narazili na požadavek nějakým způsobem stylovat jednotlivé položky (option) v helperech select nebo select_tag. Princip je jednoduchý – nejde to. Naštěstí v Rails není problém upravit přímo jejich nějakou část, pokud vám nevyhovuje (většinou pomocí vytvoření nové metody a nastavení aliasu pro původní název). Tenhle konkrétní příklad se dá vyřešit krátkým kusem kódu:
module ActionView
module Helpers
module FormOptionsHelper
def options_for_select_with_styles(container, selected = nil)
container = container.to_a if Hash === container
options_for_select = container.inject([]) do |options, element|
text, value = option_text_and_value(element)
selected_attribute = ' selected="selected"' if option_value_selected?(value, selected)
css_class = " class=\"#{element[1]}\"" if element[1] && element[1] != value
options << %(<option value="#{html_escape(value.to_s)}"#{selected_attribute}#{css_class}>#{html_escape(text.to_s)}</option>)
end
options_for_select.join("\n")
end
alias_method_chain :options_for_select, :styles
end
end
end
Kód uložte do souboru s názvem form_options_helper.rb do adresře config/initializers a teď už můžete jednoduše jako druhý parametr přidat požadovanou CSS třídu (value se potom přesouvá na třetí místo).
Bez komentářů »
Jako vášnivý čtenář všeho možného na internetu včetně diskuzí narážím semtam na názory „Ruby on Rails jsou buzzword, proto je nebudu používat“ (buzzword = „je to IN, móda, prostě TOHLE TEĎ LETÍ!!!“). Nic víc, žádný důvod, který by měl něco společného s kvalitou/nekvalitou samotného frameworku nebo Ruby jako jazyka. A důvody by se samozřejmě najít daly, Rails nejsou dokonalé a ani Ruby není dokonalé. Důvodem navíc může být i „umím skvěle PHP/Python/Javu a efektivnější je pro mě u toho zůstat“.
Způsob uvažování „je to buzzword, to nechci“ mi uniká a naopak považuji popularitu u open-source projektů za extrémně důležitý faktor. Přitahuje vývojáře a komerční firmy, které často vrací výsledek své práce komunitě. Skvěle je to vidět na jakémkoliv projektu, který je dál rozšiřitelný, například pomocí pluginů: velká komunita = víc rozšíření = méně práce pro další uživatele. Firefox, WordPress, Drupal nebo třeba Apache jsou příklady projektů, které tímto způsobem těží z široké komunity. Další výhodou je dokumentace a podpora. Víc hlav víc ví a hlavně víc hlav má víc času poradit.
Když jsem tohle napsal někomu na diskuzi v Rootu, tak jsem dostal odpověď „víc lidí, větší popularita, víc idiotů na jedné kopě, kteří ti dokáží věc znechutit“. Přiznám se, že jsem to nepochopil. Mezi větším množstvím lidí bude samozřejmě absolutní počet idiotů větší, to dává smysl. Ale nikdo mě přece nenutí komunikovat s lidmi, se kterými komunikovat nechci (ti idioti), tak jak by mi mohli něco znechutit? Prostě je vypustím, nebo je začnu brát jako komický doplněk (skvělý příklad je Astor na Živě.cz, modří určitě vědí). Navíc kdybych se tím chtěl řídit, tak musím přestat používat Windows, Firefox, MySQL a servery přeinstalovat na nějaký neznámý klon Unixu. Co ale budu dělat, když i moje nové alternativy začnou být taky populární?
Pokud se podíváme kousek do minulosti, tak podobným buzzwordem bylo XHTML. Spousta lidí v tom vidělo spásu webu, další spousta začalo hrdě ověšovat své weby ikonkami „XHTML 1.0 Strict Valid“ a někteří přestali používat tabulky i pro tabulky. Přiznám se, že mě to nechalo úplně klidným, ne protože jsem byl nějaký vizionář, ale jednoduše protože jsem byl líný a XHTML mi nic nepřinášelo. Pozdější vývoj udělal tvrdou selekci, XHTML pomalu umírá a přichází HTML5. Dalším příkladem, tentokrát úspěšného buzzwordu byl i Linux. Obrovské úspěchy se sice nekonaly, ale Linux se pomalu rozšiřuje a je to už dlouho seriózní projekt.
Pointa z toho je jednoduchá – nezáleží na tom, jestli je něco buzzword, ve výsledku stejně rozhodne kvalita a buď bublina splaskne, nebo se změní v životaschopný projekt. Takže proč se tím řídit?
Bez komentářů »
Prozatím píšu opravdu krátce – vyšla nová hlavní (major) verze frameworku Ruby on Rails. Přináší spoustu změn, o kterých se pokusím v budoucnosti rozepsat. Pro zájemce prozatím dávám odkaz na oficiální informace o vydání.
Bez komentářů »
Nejdřív jsem byl trochu udivený, že na tuhle typickou činnost neexistuje v Rails žádný plugin, ale pak mi to došlo – není moc potřeba. Google odhalil jeden užitečný kus kódu, který jsem pro větší přehlednost trochu přepsal a celé použil jako metodu třídy Password. V této podobě generuje náhodná hesla obsahující znaky a-z a 0-9, výchozí délka hesla, pokud generátor zavoláte bez parametru, je 8. Pro použití v Rails celý kód zkopírujte do souboru lib/password.rb a potom budete moci z kteréhokoliv místa kódu volat Password.generate.
class Password
ALLOWED_CHARS = ('a'..'z').to_a + ('0'..'9').to_a
def Password.generate(length = 8)
password = ''
while password.length < length
password << ALLOWED_CHARS[Kernel.rand(ALLOWED_CHARS.length)]
end
password
end
end
Bez komentářů »
Sitepoint nabízí zdarma ke stažení knihu „Build Your Own Ruby on Rails Web Applications“ na adrese http://rails.sitepoint.com. Nabídka platí po dobu 60 dnů (z nichž 18 už uplynulo, než mě napadlo o tom napsat), pouze zadáte svůj mail a obratem vám přijde odkaz ke stažení. Knížka mi přišla kvalitní, ne tak rozsáhlá jako Agile Web Development with Rails 2nd edition, ale pro začátečníky v Ruby on Rails rozhodně použitelná (trochu více se o tom rozepsal Jamis Buck na svém blogu).
Bez komentářů »
Pokud používáte Ruby on Rails, tak téměř určitě je máte nainstalované z RubyGems – balíčkovacího systému pro Ruby, který umožňuje jednoduchou a pohodlnou instalaci aplikací nebo knihoven. Při postupných updatech gemů se vám může stát, že za chvilku máte od některých hromadu verzí (u Rails se mi to stává běžně). Pokud starší verze nepotřebujete, například kvůli zpětné kompatibilitě, tak se jich můžete rychle zbavit příkazem cleanup:
gem cleanup
Bez komentářů »
Rails obsahují už delší dobu podporu pro stránkování pomocí klasického
@foo_pages, @foo = paginate(:foo, :order => 'bar' )
Problém je, že jde o trochu podivný zápis, vestavěné stránkování je nedoporučované kvůli mizernému výkonu a navíc ve verzi 2.0 bude kompletně odstraněno. Jedna možnost jak ho nahradit je napsat si vlastní, druhá využít skvěle fungujícího ekosystému pluginů. Já jako typický Rails programátor (tedy líný a nesnášející psaní rutinních věcí) jsem sáhl po druhé možnosti. Google po chvilce hledání odhalil skvělý plugin will_paginate. Proč je tak skvělý? Je jednoduchý na používání a dělá přesně co je potřeba.
Instalace klasicky v adresáři vaší aplikace:
ruby script/plugin install svn://errtheblog.com/svn/plugins/will_paginate
Samotné použití je jednoduché – prostě nahradíte volání find() objektu ActiveRecord za volání paginate a předáte mu parametr :page => params[:page], například takhle:
@foos = Foo.paginate(:all, :page => params[:page])
Výchozí počet záznamů na stránku je 15, změnit to můžete buď při volání paginate pomocí parametru :per_page nebo globálně pro určitý model přidáním metody per_page:
class Foo < ActiveRecord::Base
def self.per_page
50
end
...
end
Kromě toho samozřejmě můžete používat všechny ostatní parametry známé z find. will_paginate vám poskytne i užitečný helper pro přepínání stránek, který přidáte do view takto:
<%= will_paginate @foos %>
Vzhled helperu můžete kompletně změnit pomocí CSS a autoři pamatovali i na možnost změnit anglické Previous a Next bez potřeby předefinování helperu. Do config/environment.rb jenom přidejte:
WillPaginate::ViewHelpers.pagination_options[:prev_label] = '« Předchozí'
WillPaginate::ViewHelpers.pagination_options[:next_label] = 'Další »'
To je vše a můžete vesele stránkovat.
Bez komentářů »
Pokud generujete URL v odesílaných e-mailech, tak logicky potřebujete, aby byly absolutní. Na druhou stranu psát absolutní URL do kódu je nepohodlné kvůli testování. Samozřejmě je možný výsledný URL zkopírovat do prohlížeče a tam ručně změnit adresu, ale to zkrátka není ono. Řešením je nastavit výchozí parametry pro volání url_for.
V ActionMaileru nejsou potřebné proměnné k dispozici, takže je musíte předat při vytváření e-mailu:
class FooController < ApplicationController
def send_email
url_options = {:host => request.host, :protocol => request.protocol.gsub('://', '')}
url_options[:port] = request.port unless [80, 443].include?(request.port)
mail = FooMailer.create_bar(url_options)
...
end
end
Tělo ActionMaileru potom vypadá takto:
class FooMailer < ActionMailer::Base
include ActionController::UrlWriter
def bar(url_options)
...
default_url_options.merge!(url_options)
end
end
V šabloně e-mailu potom můžete normálně používat url_for s parametrem nly_path => false. Stejně tak musíte vždy explicitně definovat kontroler, neplatí že by byl použitý kontroler, ze kterého bylo voláno vytvoření e-mailu:
<%= link_to('click here', url_for(:only_path => false, :controller => 'foo', :action => 'index')) %>
Bez komentářů »
Tohle je další věc, která nefunguje out-of-box. Pokud zkusíte url_for nebo cokoliv podobného v šablonách ActionMaileru, nikam se nedostanete. V dokumentaci je navíc poměrně depresivní upozornění, že to zkrátka nejde. Naštěstí to jde, stačí includovat UrlWriter:
class EshopOrderMailer < ActionMailer::Base
include ActionController::UrlWriter
....
end
Bez komentářů »
|