Posted by Dibi Store
Mon, 26 May 2008 05:38:00 GMT
Passenger è un modulo apache sviluppato di recente da phusion che permette il deploy di applicazioni rails anche in grande scala.
La cosa interessante è che questa soluzione sta già diventando la de-facto per una buona parte di sviluppatori rails. Avrò occasione di provare questo prodotto al più presto, e quindi di darvi maggiori info e feedback, nel frattempo vi lascio alcuni link utili per iniziare a darci un occhiata.
modrails.com: sito ufficiale.
28 mod_rails / Passenger Resources To Help You Deploy Rails Applications Faster: link utili per iniziare da subito.
Ask Your Doctor About mod_rails: interessante articolo scritto da Geoffrey Grosenbach.
Posted in ruby on rails | Tags deploy, passenger | no comments | no trackbacks
Posted by Dibi Store
Thu, 20 Mar 2008 14:28:00 GMT
Il plugin acts_as_taggable_on_steroids è molto utile quando abbiamo bisogno di taggare i nostri modelli in rails. Recentemente mi sono trovato a dover implementare una funzionalità di paginazione che tenesse conto dei risultati della ricerca per tag. Come plugin per la paginazione usiamo will_paginate e per aggiungere la funzionalità mi è bastato inserire questo pezzo di codice alla fine del file environment.rb.
module ActiveRecord
module Acts
module Taggable
module SingletonMethods
def paginate_tagged_with(*args)
options = find_options_for_find_tagged_with(*args)
options.blank? ? WillPaginate::Collection.new(1, 1, 0) : paginate(:all, options)
end
end
end
end
end
Dietro le quinte stiamo definendo un metodo che usa paginate al posto di file, WillPaginate::Collection.new(1, 1, 0) serve invece per evitare di ricevere l'errore undefined method `page_count' for []:Array quando l'array di risultati è vuoto.
Posted in ruby on rails | no comments | no trackbacks
Posted by Dibi Store
Wed, 09 Jan 2008 08:22:00 GMT
Ruby on Rails è un framework di qui ho già sicuramente parlato molto, infatti ci lavoro fortunatamente ogni giorno a stretto contatto. Credo che chiunque lo abbia utilizzato almeno una volta abbia voluto sapere cosa succede realmente dietro le quinte di questa gemma. Per questo ho scritto questo articolo che descrive il processo di inizializzazione del framework. Per gli esempi prenderò come riferimento l'attuale versione 2.0.2 .
Innanzitutto consiglio per seguire meglio gli esempi di creare un progetto vuoto che chiameremo course, vi consiglio di tenere questo progetto sempre disponibile, in quanto verrà usato direttamente in articoli futuri. L'ultimo passo è quello di 'congelare' l'attuale versione di rails con il comando:
rails course
cd course/
rake rails:freeze:gems
In alterativa potete scegliere il nome che volete, non ha particolare importanza. Aprendo il file config/database.yml, noterete subito che l'adattatore di default non è più mysql, bensì sqlite3. Ciò ci da un vantaggio immediato, infatti non abbiamo bisogno di andare a creare il database manualmente (anche se avremo potuto usare il comando rake db:create oppure rake db:create:all). A questo punto aprite il vostro IDE preferito, e iniziamo il nostro tour!
Il file dispatcher.rb dentro alla directory /public, è il primo che normalmente viene analizzato (in circostanze normali), nella prima riga vediamo che viene specificato come commento (un commento speciale a dire il vero) il percorso del nostro interprete. Ciò potrà non interessare a molti, ma ciò potrebbe dare in qualche modo fastidio alla macchina in qui effettuerete l'eventuale deploy (analizzeremo anche quello in futuro!) Sappiate che potete usare un trucchetto in molti casi, ossia dichiarare /usr/bin/env ruby, oppure dichiarare esplicitamente il percorso nel momento della generazione del progetto utilizzando l'opzione -r (provate in console a dare il comando rails -h se non lo avete mai fatto). Bando alle ciance, l'unica cosa importante è che viene 'richiesto' il file /config/environment.rb, ammeno che rails non sia gia stato inizializzato (non volete mica carica tutto il framework ogni volta, vero?).
Il file /config/environment.rb dapprima dichiara la versione di rails da utilizzare, poi caricherà il file boot.rb, che si trova nella stessa directory. Questo file dapprima definirà la variabile RAILS_ROOT che indicherò appunto la directory radice del progetto, dopodichè deciderà da dove andare a caricare il framework, in sostanza se è presente una directory /vendor/rails, il framework sarà caricato da li, altrimenti sarà caricato dalla vostra gemma presente nel sistema.
Qui possiamo notare una prima cosa interessante. Osservando il metodo preinitialize, all'incirca alla riga 29, potete notare che rails tenta di caricare un file, precisamente in /config/preinitializer.rb, ovviamente noi questo file andremo a crearlo (siamo [hacker|curiosi|non abbiamo un * da fare] o no?), e ci inseriremo il codice seguente, dopodichè avvieremo il server:
puts "Ciao dal preinizializzatore!\n\n"
# Salviamo e da console diamo:
./script/server
dibistore:course oskar$ ./script/server
Ciao dal preinizializzatore!
=> Booting Mongrel (use 'script/server webrick' to force WEBrick)
=> Rails application starting on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
** Starting Mongrel listening at 0.0.0.0:3000
** Starting Rails with development environment...
** Rails loaded.
** Loading any Rails specific GemPlugins
** Signals ready. TERM => stop. USR2 => restart. INT => stop (no restart).
** Rails signals registered. HUP => reload (without restart). It might not work well.
** Mongrel 1.1.3 available at 0.0.0.0:3000
** Use CTRL-C to stop.
Fantastico, abbiamo appena scoperto un modo per inserire del codice ancora prima che venga caricato qualsiasi dato, questo apre molte possibilità, ma non è finita qui, infatti a questo punto caricheremo il file /vendor/rails/railties/lib/initializer.rb. Due parole per capire meglio: questa parte di rails, (railties) serve a collegare insieme i vari componenti (active record, action pack eccetera). Infatti nelle prime righe vengono impostate alcune costanti, aggiunti dei file alla load_path (tramite $LOAD_PATH.unshift File.dirname(__FILE__)) e dichiarato l'environment attuale (molto importante).
Il metodo che ora verrà chiamato è self.run, che potete ispezionare con calma, valutando le possibilità, poco sotto questo metodo vedete anche (commentato) l'elenco delle cose che vengono caricate da rails e il loro ordine, che qui traduco per semplicità:
# * #controlla la versione di ruby (deve essere almeno la 1.2 ma non la 1.3)
# * #inserisci i percorsi dei file nella load_path
# * #carica i vari frameworks (active record ecc.)
# * #inserisci altri percorsi nella load_path
# * #aggiungi la directory dei plugin alla load_path (ma non li carica)
# * #carica il file dell'environment corrente (/config/envrionments/whatever)
# * #inizializza encoding
# * #inizializza database (prepara connessione ecc.)
# * #inizializza il logger
# * #initializza e configura il logging dei vari frameworks
# * #inizializza le viste dei frameworks
# * #inizializza le dipendenze
# * #inizializza whiny_nil (estende la class Nil, dandoci degli errori più utili)
# * #inizializza directory temporanee
# * #inizializza le configurazioni dei frameworks
# * #aggiunge altri percorsi alla load_path
# * #carica i plugins
# * #carica gli observers (/config/initializers/)
# * #inizializza il processo di routing
# * #carica eventuali metodo definiti in /config/environment.rb chiamati after_initialize
# * #carica il tutto
Il nome inizializzatore è più che azzecato, ovviamente non posso descrivere ora nel dettaglio ognuno di questi passi, per qui lo farò man mano nel tempo e pubblicherò degli articoli più dettagliati qui sul blog. Vi consiglio di continuare da soli a questo punto il processo di riscoperta dell'inizializzazione, in quanto è tempo sempre ripagato (che bello ruby).
Posted in ruby on rails | Tags rails | no comments | no trackbacks
Posted by Dibi Store
Fri, 07 Dec 2007 15:20:00 GMT
Sarà l'ennesimo post, oggi ne parlano tutti, è finalmente giunto il rilascio di rails2.0. Bhe non provo nemmeno ad agiornarela mia release oggi, perchè immagino ci sia un traffico pazzesco, e rischio di rimanere a metà con l'installazione, anche se io personalmente gia da mesi ho una versione stabile della gemma e una di sviluppo, comunque fate voi, ma ne vale veramente a pena :)
Posted in ruby on rails | Tags rails20 | no comments | no trackbacks
Posted by Dibi Store
Tue, 27 Nov 2007 09:15:00 GMT
Piccolo trucchetto. Se il vostro progetto è gestito tramite subversion, quando generate files tramite script/generate in rails potete usare l'opzione -c per aggiungerli in modo automatico. Qui trovate una bella lista di consigli e trucchetti per lavorare in sintonia con subversion.
Posted in ruby on rails | no comments
Posted by Dibi Store
Thu, 22 Nov 2007 12:38:00 GMT
Restful authentication è un plugin che ci permette di generare le procedure di registrazione in rails. Purtroppo qualche giorno fa è stato trovato un bug, potete leggere tutti i dettagli e la soluzione qui.
In sostanza inserendo un codice di validazione nullo, si viene automaticamente loggatti come primo utente! Leggetevi il link sopra per capire bene di cosa sto parlando.
Posted in ruby on rails | Tags authentication | no comments
Posted by Dibi Store
Tue, 20 Nov 2007 11:54:00 GMT
Se ottenete questo errore quando usate rake per avviare memcached:
undefined method `[]' for nil:NilClass
Sinifica che avete una versione buggata del plugin cache_fu. In sostanza per farla vreve andate sulla directory del plugin, poi su task e aprite il memcached rake e sostituitelo con questo:
namespace :memcached do
desc "Start memcached locally"
task :start do
memcached config_args
end
desc "Restart memcached locally"
task :restart do
Rake::Task['memcached:stop'].invoke
Rake::Task['memcached:start'].invoke
end
desc "Stop memcached locally"
task :stop do
`killall memcached`
end
end
def config
return @config if @config
config = YAML.load_file(RAILS_ROOT + '/config/memcached.yml')
@config = config['defaults'].merge(config['development'])
end
def config_args
config
args = {
'-p' => Array(@config['servers']).first.split(':').last,
'-c' => @config['c_threshold'],
'-m' => @config['memory'],
'-d' => ''
}
args.to_a * ' '
end
def memcached(*args)
`/usr/bin/env memcached #{args * ' '}`
end
In pratica non venivano richiamati gli argomenti (qui l'errore che avete ricevuto) perchè non veniva richiamato il metodo args, in piu il percorso relativo al file di configurazione era sbagliato, meglio metterlo con RAILS_ROOT.
Mi stupisco ancora che non venga fissato in quanto cosi è inutilizzabile.
Enjoy
Posted in ruby on rails | Tags cache_fu | no comments
Posted by Dibi Store
Sat, 17 Nov 2007 11:31:00 GMT
Con l'arrivo di rails 2.0, è ormai deprecato usare file con estensione rhtml, invece è piu conveniete usare i file con estensione erb. Fin qui tutto chiaro, apparte magari la poca voglia di andare a modificare a mano tutti i files delle viste, per qui ecco qui uno script che lo farà in automatico per voi, addirittura aggiornano svn, trovato su caboo e modificato da me per supportare anche i files rjs.
namespace 'views' do
desc 'Renames all your rhtml views to erb'
task 'rename' do
Dir.glob('app/views/**/*.rhtml').each do |file|
puts `svn mv #{file} #{file.gsub(/\.rhtml$/, '.html.erb')}`
end
Dir.glob('app/views/**/*.rjs').each do |file|
puts `svn mv #{file} #{file.gsub(/\.rhtml$/, '.js.erb')}`
end
end
end
Da notare che nella versione originale i files venivano rinominati semplicemente con erb.
Io invece preferisco anteporre anche l'html, per maggiore chiarezza.
Inoltre potete adattare il tutto a qualsiasi estensione, senza problemi.
Per usarlo, invece, mettete il file nella directory /lib/task/views.rake, e lanciatelo con:
rake views:rename
Posted in ruby on rails | Tags rails20 | 1 comment
Posted by Dibi Store
Sun, 11 Nov 2007 11:41:00 GMT
Aggiornare un record di database tramite active record e ruby on rails è molto semplice, infatti abbiamo a dispozione, tra gli altri, due semplici metodi, update_attribute, che accetta 2 parametri, ossia i nome del campo e l'attributo, e update_attributes, che invece accetta un hash di chiavi e valori.
C'è da ricordardi, però, che in questo caso, active recocord NON esegue la validazione prima del salvataggio, fate pure delle prove se volete. L'alternativa è quella di usare un codice simile al seguente:
user = User.find(3)
user.name = 'john'
user.save
In questo caso, il nome verrà validato, in quanto la validazione viene richiamata prima del salvataggio di un record. Potete usare una tecnica simile anche quando aggiornate da un form:
user = User.find(params[:id])
user.name = params[:user][:name]
user.save
Per il resto, è tutto molto semplice, ma tenete questa cosa bene in mente.
Posted in ruby on rails | Tags activerecord | no comments
Posted by Dibi Store
Wed, 07 Nov 2007 10:22:00 GMT
Quando scriviamo del codice in ruby, non sempre risulta efficente, per qui potremmo trovarci nelle situazioni di usare una tecnica molto piu lenta rispetto ad un altra, che magari crediamo sbagliata. Rimanere nel dubbio, non è una buona cosa, specialmente per noi programmatori, per qui in questo articolo illustro 2 tecniche: la prima per testare il codice prodotto con ruby, e l'altra per testare la velocità delle sql in rails.
Performance in Ruby
Ruby dispone di una libreria chiamata Benchmark, che ci permette di testare la velocità del codice, ci basterà quindi includela nel nostro test, e provare un esempio come il seguente (preso da programming ruby):
require 'benchmark'
include Benchmark
string = "Stormy Weather"
m = string.method(:length)
bm(6) do |x|
x.report("call") { 10_000.times { m.call } }
x.report("send") { 10_000.times { string.send(:length) } }
x.report("eval") { 10_000.times { eval "string.length" } }
end
produces:
user system total real
call 0.020000 0.000000 0.020000 ( 0.045998)
send 0.040000 0.000000 0.040000 ( 0.051318)
eval 0.130000 0.000000 0.130000 ( 0.177950)
Il che non è niente male, giocateci un po per capire come sfruttarlo.
Performance in Rails
Rails ci mette a disposizione la classe benchmark per testare la velocità delle sql, che è utilissima, potete includere del codice simile al seguente in un vostro modello, richiamando poi una qualsiasi azione di quel modello, potrete vedere nel log il tempo che ci ha messo:
User.benchmark("adding and deleting 1000 users") do
1000.times do
State.create(:name => 'something')
x = State.find_by_name('something')
x.destroy
end
end
Spero prossimamente di poter fare degli articoli dettagliati riguardanti le performance, intanto vi lascio sperimentare un po :)
Posted in ruby on rails | Tags performance | no comments