18 Dec
matte

matte il 18 December 2013 parla di Altro

E’ online il nostro nuovo blog

Abbiamo deciso di cambiare veste al nostro blog, lo trovate qui. Già da molto tempo abbiamo smesso di scrivere su Rails on the road e da adesso ogni annuncio, suggerimento od osservazione la trovate al nuovo indirizzo http://www.extendi.it/blog.

Grazie a tutti

29 Dec
matte

matte il 29 December 2011 parla di Job

Ruby on Rails a Firenze

Ciao a tutti! Cerchiamo aiuto per alcuni progetti in Ruby on Rails a partire dal nuovo anno (2012):

  • Ruby on Rails
  • MySQL
  • jQuery

Interessato? Mandaci una mail o vieni a trovarci a Lastra a Signa in Via A. Diaz, 60.

Hi all! We are searching a Ruby on Rails developer starting from the beginning of 2012.

  • Ruby on Rails
  • MySQL
  • jQuery

Interested? Send us an email or visit us at Lastra a Signa in Via A. Diaz, 60.

9 Dec
matte

matte il 9 December 2011 parla di Altro

Mercatini di Natale & Apple Store

Un bel post dall’Apple Store era tanto che non si faceva! Ecco una foto da Monaco di Baviera!

photo1

11 Apr
matte

matte il 11 April 2011 parla di Altro

Recipefy é in TV!

Guardate qua: http://bit.ly/el4iOk

21 Jan
matte

matte il 21 January 2011 parla di Rails3, plugin

enhanced_form_tag_helper plugin e Rails 3

Mi sono trovato a fare un porting da Rails 1.2.3 a 3.0.3. A parte dover aggiornare quasi tutto mi sono imbattuto in un valido sostituto dell’enhanced_form_tag_helper plugin.

Potete tranquillamente sostituirlo con form_helper_css.

Utilizza gli stessi nomi di classe e non ho nemmeno dovuto aggiornare il foglio di stile.

20 Sep
duccio

duccio il 20 September 2010 parla di Comunicati

Feedmyapp has been acquired by OnClick Solutions ltd

We are excited to announce that Feedmyapp has been acquired by OnClick Solutions ltd!

Feedmyapp was born three years ago as an experiment and has been very successful beyond our expectations, now continues the race! It will grow even further, there will be interesting changes and exciting new features that make the service better and better … so continue to get your Web 2.0 daily dose!

We can only wish good luck to Neran, the new Feedmyapp manager, and thanks to everyone for joining us with great passion. We also thank the sponsors who believed in Feedmyapp and all editions managers who contributed to make Feedmyapp famous worldwide.

For Extendi team is time to try something different … Stay tuned!

20 Sep
duccio

duccio il 20 September 2010 parla di Comunicati

Feedmyapp è stata comprata da OnClick Solutions Ltd

Siamo eccitati nell’annunciarvi che Feedmyapp è stata comprata da OnClick Solutions ltd!

Feedmyapp è nata 3 anni fa come esperimento ed ha avuto successo ben oltre ogni nostra aspettativa, adesso passa di mano e continua la corsa! Crescerà ancora, sono previsti cambiamenti interessanti e nuove eccitanti funzionalità che renderanno il servizio sempre migliore… continuate a prendere la vostra daily web 2.0 dose!

Non ci resta che augurare buona fortuna a Neran, il nuovo manager di Feedmyapp, e ringraziare tutti per averci seguito con grande passione. Vogliamo inoltre ringraziare gli sponsor che hanno creduto in Feedmyapp ed i manager di tutte le edizioni che con il loro lavoro hanno contribuito a farci conoscere nel mondo.

Per noi di Extendi è il momento di dedicarsi a qualcosa di diverso… Stay tuned!

16 Jul
duccio

duccio il 16 July 2010 parla di Rails3, plugin

Rails3 e fleximage

Ho provato ad installare la gemma con rails3 ma non ha funzionato, il problema è nel template “.flexi”. La soluzione più veloce è quella di spostare dal template flexi al controllore, le operazioni sulle immagini e renderizzare con il send_data. Ma se non volete sporcare l’azione del controllore, allora provate a scaricare la fork del progetto di Squeegy.

Praticamente ho solo ridefinito il template per il render in rails3:

    1 module ActionView
    2   module TemplateHandlers
    3     class Rails3View < TemplateHandler
    4       include Compilable
    5       class TemplateDidNotReturnImage < RuntimeError #:nodoc:
    6       end
    7 
    8       def compile(template)
    9         <<-CODE
   10         @template_format = :flexi
   11         controller.response.content_type ||= Mime::JPG    
   12         result = #{template.source}
   13         requested_format = (params[:format] || :jpg).to_sym
   14         begin
   15           # Raise an error if object returned from template is not an image record
   16           unless result.class.include?(Fleximage::Model::InstanceMethods)
   17             raise TemplateDidNotReturnImage, ".flexi template was expected to return a model instance that acts_as_fleximage, but got an instance of instead."
   18           end
   19           # Figure out the proper format
   20           raise 'Image must be requested with an image type format.  jpg, gif and png only are supported.' unless [:jpg, :gif, :png].include?(requested_format)
   21           result.output_image(:format => requested_format)
   22         rescue Exception => e
   23           e
   24         end
   25         CODE
   26       ensure
   27         GC.start
   28       end
   29     end
   30   end
   31 end

C’era anche un piccolo problema nell’image_file_url con il formato del’url, così in model.rb ho aggiunto file = open(URI.parse(URI.encode(file_url))) per evitare il problema.

13 Jul
matte

matte il 13 July 2010 parla di Configurazioni, Rails3, plugin

will_paginate e Rails3

Sicuramente avrete iniziato a provare Ruby on Rails 3. Per paginare i nostri record agevolmente possiamo usare il plugin will_paginate.

Per installarlo basta aggiungere al file Gemfile la seguente riga di codice in modo da prendere il codice del branch per Rails 3:

    1 gem 'will_paginate', :git => 'git://github.com/mislav/will_paginate.git', :branch => "rails3" 
1 Apr
duccio

duccio il 1 April 2010 parla di Rails Snippet

Nested Layout

Se volete usare un layout dentro un altro layout potete utilizzare il plugin nested_layout che con l’helper inside_layout, vi consente di specificare il template in cui includere il contenuto del blocco successivo, vediamo un esempio:

    1 <% inside_layout 'site' do -%>
    2     <div class="hello">
    3       <h1>Ciao</h1>
    4       <%= yield %>
    5     </div>
    6 <% end -%>

Questa è una soluzione elegante e funzionale, ma se volete qualcosa di più “artigianale” vi fate il metodo inside_layout nell’application helper e lo usate se il layout che state facendo deve ereditare un wrapper esterno:

    1   def inside_layout(layout)
    2     @content_for_layout = self.output_buffer
    3     self.output_buffer = render(:file => "layouts/#{layout}")
    4   end

E nel vostro layout lo usate insede_layout specificando il nome del layout in cui includere i contenuti:

    1 <% content_for :header do  %>
    2 <ul class="menu">
    3   <li>menu 1</li>
    4   <li>menu 2</li>
    5   <li>menu 3</li>
    6   <li>menu 4</li>
    7 </ul>
    8 <% end %>
    9 
   10 <div class="lcol">
   11   <%= yield :sidebar %>
   12 </div>
   13 
   14 <div class="content">
   15   <%= yield %>
   16 </div>
   17 
   18 <% inside_layout 'site' %>

Il layout “site.erb” sarà qualcosa di questo tipo:

    1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    2 <html xmlns="http://www.w3.org/1999/xhtml">
    3 <head>
    4   <title>Title</title>
    5   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    6   <meta name="description" content="<%= @page_desc %>" />
    7   <meta name="keywords" content= "<%= @page_keyword %>" />
    8   <%= javascript_include_tag :defaults %>
    9   <%= yield :script %>
   10 </head>
   11 <body>
   12 <div id="page">
   13   <div id="header">
   14     <h1>LOGO</h1> 
   15 
   16     <ul class="menu">
   17       <li>menu 1</li>
   18       <li>menu 2</li>
   19       <li>menu 3</li>
   20       <li>menu 4</li>
   21     </ul>
   22     <%= yield :header %>
   23   </div>
   24   
   25   <div id="cont">
   26     <%= yield %>
   27   </div>
   28   
   29   <div id="footer">
   30     <ul class="menu">
   31       <li>menu 1</li>
   32       <li>menu 2</li>
   33       <li>menu 3</li>
   34       <li>menu 4</li>
   35     </ul>
   36   </div>
   37 </div>
   38 </body>
   39 </html>
30 Mar
duccio

duccio il 30 March 2010 parla di Rails Snippet, Risorse

Princely: rails wrapper per Prince XML

Prince XML non è una libreria opensource e necessita di una licenza che va da i 495$ fino ai 3800$, esiste anche una versione gratuita che aggiunge un watermark in alto a destra alla pagina. Se l’applicazione che state sviluppando si basa molto sui report di stampa, vi raccomando questa libreria che è indubbiamente la più flessibile e ha il vantaggio di usare i CSS per applicare gli stili al pdf. Princely è un wrapper per rails che permette di utilizzare gli strumenti di princeXML dalla vostra applicazione rails.

potete installarlo come gemma:

    1 config.gem 'princely', :source => 'http://gemcutter.org'

o come plugin:

    1 ./script/plugin install git://github.com/mbleigh/princely.git 
19 Feb
matte

matte il 19 February 2010 parla di Confs, Risorse

La prima conferenza Rails Online => Rails 3

Ieri si è svolta alle ore 18 italiane la prima conferenza Rails Online completamente gratuita e molto interessante. Ci sono stati solamente alcuni inconvenienti con la piattaforma utilizzata per fare il broadcasting audio e video: in totale ci sono stati 3 blocchi (almeno su Mac e Snow Leopard).

L’argomento principale è stato Rails 3: novità, upgrade da Rails 2 e l’utilizzo di Middleware Rack.

Potete trovare le slide della conferenza ai seguenti indirizzi:

15 Dec
duccio

duccio il 15 December 2009 parla di Ajax/Web 2.0, Comunicati, Confs, Risorse

Go!webdesign: primo Workshop Italiano dedicato al WebDesign 2.0

Go!webdesign una giornata all’insegna delle tematiche più discusse sul mondo del webdesign 2.0, dai consigli degli esperti in sala a case history di grandi realtà italiane.

julius

Durante l’evento saranno spiegate svariate tecniche e novità sull’uso di linguaggi legati al webdesign e software Adobe. Ci sarà la possibilità di partecipare alla tavola rotonda e discutere sui propri progetti o idee.

Infine grandi sorprese con una gara creativa, buffet e possibilità di ricevere via email tutto il materiale trattato durante l’evento.

Extendi sarà media partners all’evento.

media

15 Dec
duccio

duccio il 15 December 2009 parla di Rails Snippet

Ignorare il default_scope

Può essere utile mettere un default_scope per filtrare a monte determinati contenuti, il problema è che se usate questo tipo di scope, verrà applicato sempre anche quando magari non serve.

Per evitare il problema o usate i named_scope, oppure usate il with_exclusive_scope.

    1 default_scope :conditions => ["field = ?", valore], :order => 'published_at DESC'

Se usate il with_exclusive_scope ingnorerete il default_scope:

    1 Content.send(:with_exclusive_scope) {
    2   Content.find(:all)
    3 }
1 Dec
silvio

silvio il 1 December 2009 parla di Rails Snippet, Risorse, Tutorial

Eager loading e query con condizioni su associazioni polimorfiche e single table inheritance

Come apprendiamo da questo vecchio post di Duccio, a partire dalla versione 2.1.0 di Rails è possibile effettuare query con eager loading su modelli polimorfici, ma tuttora non è possibile applicarci delle condizioni.

Un’interrogazione all’Active Record come la seguente funziona soltanto se il modello Account non è polimorfico:

usr = User.find(:first, :include => :accounts, :conditions => ["accounts.name = 'Principale'"])

Cerchiamo dunque di ovviare al problema dell’ActiveRecord che non consente di applicare condizioni sulla tabella polimorfica inclusa in eager loading.

La modellazione di esempio è la seguente: abbiamo delle “risorse” polimorfiche, da cui ereditano per STI i modelli Picture e Video che dunque sono polimorfici ed ereditari; queste risorse sono associate ai modelli Activity e Article.

class Resource < ActiveRecord::Base
belongs_to :resourceable, :polymorphic => true
end

class Picture < Resource
end

class Video < Resource
end

class Activity < ActiveRecord::Base
has_many :pictures, :as => :resourceable,  :dependent => :destroy
has_many :videos, :as => :resourceable,  :dependent => :destroy
end

class Article < ActiveRecord::Base
has_many :pictures, :as => :resourceable, :dependent => :destroy
end

Cerchiamo adesso di ottenere tutte le immagini associate ad un articolo, di cui ad esempio conosciamo solo parte del titolo.

Con questa modellazione, la seguente interrogazione all’Active Record ritornerebbe un errore:

items = Picture.find(:all,
                     :include => [:resourceable],
                     :conditions => ["LOWER(resourceable.title) LIKE ?", "%titolo_cercato%"])

Per risolvere questo problema è necessario specificare l’inner join, evitando di usare l’include:

items = Picture.find(:all,
                     :joins => "INNER JOIN articles ON articles.id = pictures.resourceable_id",
                     :conditions => ["LOWER(articles.title) LIKE ?", "%titolo_cercato%"])

Per ulteriori approfondimenti guardate la guida Active Record Query Interface e la documentazione delle API

13 Nov
matte

matte il 13 November 2009 parla di Risorse

Rails for PHP developers

Dovendo effettuare il porting di una parte di codice PHP in Rails ho trovato molto utile questo sito soprattutto come referenza per capire quali funzioni ruby utilizzare.

13 Oct
duccio

duccio il 13 October 2009 parla di Rails Snippet, Risorse, Tutorial

Ottimizzare le query con EXPLAIN di MySQL

L’ottimizzazione delle query è sempre un punto cruciale per ogni progetto ed è sicuramente una parte fondamentale del processo di ottimizzazione di un’applicazione Web. Non credo di dirvi niente di nuovo ma, considerato che non ne ho mai parlato direttamente, riporto un piccolo riassunto.

Ip plugin query_analyzer vi consente di avere l’EXPLAIN delle query direttamente nel log:

    1 ./script/plugin install http://svn.nfectio.us/plugins/query_analyzer

La sintassi per vedere l’explain di una query da shell mysql:

    1 EXPLAIN [EXTENDED] SELECT select_options

L’explain restituisce informazioni per ogni tabella coinvolta nella query, vediamo un esempio in cui mancano indici:

picture-1

In questo caso il select_type è simple, non ci sono join, il type è ALL cioè cerca su tutte le righe, e nessuna possible_keys. Aggiungendo un indice al campo action della tabella contents (La query effettuata è Content.find_by_action(”nome azione”)) si ottiene questo risultato:

picture-2

Migliorando di fatto il tempo necessario per eseguire la query, tempo ulteriormente migliorabile usando il caching di Mysql.

In generale col query_analyzer (con l’EXPLAIN di mysql) potrete trovare i seguenti valori per ogni campo visualizzato:

Select_type

E’ il tipo di SELECT:

  • SIMPLE select semplice senza join o sottoquery
  • PRIMARY outermost SELECT
  • DEPENDENT UNION seconda o ultima SELECT in una unione
  • UNION RESULT risultato di una UNION
  • SUBQUERY prima SELECT in una subquery
  • DEPENDENT SUBQUERY prima SELECT in un una subquery dipendente da un altra query
  • DERIVED subquery nel FROM
  • UNCACHEABLE SUBQUERY subquery non cachabile

Table

E’ la tabella su cui si esegue la query.

Type

E’ il tipo di Join e sono in ordine dal migliore al peggiore:

  • system: la tabella ha una sola riga è un caso particolare di const
  • const: la tabella ha al massimo una riga corrispondente, che viene letta all’inizio della query. Poichè c’è una sola riga, i valori delle colonne in questa riga sono considerati come costanti da parte dell’optimizer. Le tabelle const sono molto veloci perché vengono letti solo una volta.
  • eq_ref: viene letta una riga per ogni combinazione di righe delle tabelle precedenti. È usato quando tutte le parti di un indice sono utilizzate dalla join e l’indice è una PRIMARY KEY o UNIQUE.
  • ref: tutte le righe con i corrispondenti valori di indice vengono letti da questa tabella per ogni combinazione di righe delle tabelle precedenti. ref viene utilizzato se la join utilizza solo la parte più a sinistra dell’indice o se la chiave non è un indice PRIMARY KEY o UNIQUE (in altre parole, se l’unione non può selezionare una sola riga sulla base del valore della chiave). Va bene quando il set di righe di unione è piccolo.
  • fulltext: ricerca di tipo fulltext
  • range: solo le righe che si trovano in un determinato intervallo vengono recuperate, utilizzando un indice per selezionare le righe. La colonna chiave della riga di output indica che l’indice viene utilizzato. Il key_len contiene la parte più lunga chiave che è stata utilizzata. La colonna ref è NULL per questo tipo. Viene usata per =, <>, >, >=, < , <=, IS NULL, <=>, BETWEEN, o IN()
  • index: è come ALL ma si cerca sull’indice
  • ALL: viene fatta una scansione completa della tabella, per ogni combinazione di righe delle tabelle precedenti. Questo normalmente non va bene, si risolve mettendo indici.

Possible_keys

La colonna possible_keys indica gli indici che MySQL può scegliere per trovare le righe in questa tabella.

Key

La colonna key è l’indice che MySQL ha effettivamente deciso di utilizzare. MySQL, può decidere di utilizzare sia uno degli indici possible_keys per cercare le righe, sia la primary key.

E ‘possibile che key sia il nome di un indice che non è presente in possible_keys. Questo può accadere se nessuno degli indici possible_keys è adatto per la ricerca, ma tutte le colonne selezionate dalla query sono colonne di qualche altro indice. Cioè, l’indice copre le colonne selezionate, quindi anche se non viene utilizzato per determinare le righe da recuperare, lì la ricerca è comunque più veloce.

Key_len

La colonna key_len indica la lunghezza della chiave che MySQL ha deciso di utilizzare. La lunghezza è NULL se la colonna key dice NULL. Si noti che il valore di key_len consente di determinare quante parti di più chiavi MySQL utilizza effettivamente.

Ref

La colonna ref mostra quali colonne o costanti sono confrontati con l’indice per selezionare le righe della tabella.

Rows

La colonna righe indica il numero di righe MySQL ritiene che esso deve verificare l’esecuzione della query. Per i db innoDB non sempre il numero di righe stimato è quello reale.

Extra

Questa colonna contiene ulteriori informazioni su come MySQL risolve la query. Dicimo che se trovat scritto Using where e type è ALL o index c’è qualche problema sulla vostra query.

21 Sep
silvio

silvio il 21 September 2009 parla di Ajax/Web 2.0, Comunicati, Release

BudgetUp è online!

Siamo molto eccitati nell’annunciarvi che dopo mesi di duro lavoro BudgetUp è stato lanciato!

budgetupit BudgetUp ti permette di gestire agilmente spese, guadagni e l’andamento delle tue finanze.

Abbiamo appena cominciato l’avventura e ringraziamo in anticipo chiunque voglia darci consigli o riportare errori, aiutandoci così a renderlo un prodotto migliore.

16 Sep
silvio

silvio il 16 September 2009 parla di Risorse, plugin

Ferret Browser

Oggi mentre stavo indagando su un problema con il Ferret che non indicizzava un modello, mi sono imbattuto su ferret-browser.

Ferret Browser

Questa simpatica utility ci consente di navigare nell’indice del Ferret tramite il browser, di analizzare la struttura e gli attributi dell’indice, nonché di visualizzare qualche statistica sui termini indicizzati per ogni attributo.

ferret-browser viene installato insieme alla gemma del Ferret e si esegue da console, indicando come parametro il path dell’indice, ad esempio:

ferret-browser /Users/silvio/Sites/mio-progetto/index/development/nome-modello

In questo modo viene avviato WEBrick ed è sufficiente puntare il browser su http://localhost:3301/

8 Sep
matte

matte il 8 September 2009 parla di Configurazioni, Mac

Upgrade a Snow Leopard

Oggi è arrivato in office Snow Leopard e abbiamo deciso di aggiornare i nostri iMac sperando di non incappare in qualche incompatibilità con i software che utilizziamo. Tutto è filato liscio (non abbiamo dovuto ripristinare backup) anche se ci sono stati alcuni inconvenienti. Per questo vi consiglio (a parte un backup dei file più importanti) di salvare i seguenti file che l’aggiornamento va a sovrascrivere, nel caso in cui abbiate avuto la necessità di cambiarli:

/etc/hosts
/etc/apache2/httpd.conf

Inoltre se utilizzate MacPorts per installare i pacchetti software (tipo ruby, mysql, tomcat) effettuate un backup su file del nome dei pacchetti installati con il comando:

port installed > myports.txt

Una volta effettuato l’aggiornamento non è stato più possibile lanciare il comando port, ottenendo il seguente errore:

    1 dlopen(/opt/local/share/macports/Tcl/pextlib1.0/Pextlib.dylib, 10): no suitable image found.  Did find:
    2   /opt/local/share/macports/Tcl/pextlib1.0/Pextlib.dylib: mach-o, but wrong architecture
    3     while executing
    4 "load /opt/local/share/macports/Tcl/pextlib1.0/Pextlib.dylib"
    5     ("package ifneeded Pextlib 1.0" script)
    6     invoked from within
    7 "package require Pextlib 1.0"
    8     (file "/opt/local/bin/port" line 40)

Per risolvere il problema su Snow Leopard scaricate ed installate http://distfiles.macports.org/MacPorts/MacPorts-1.8.0-10.6-SnowLeopard.dmg

Poi aggiornate il repositorio dei pacchetti con il comando

sudo port selfupdate

Per ricompilare tutti i pacchetti lanciate il comando:

sudo port upgrade --force installed

per aggiornare solamente quelli più vecchi:

sudo port upgrade outdated

A questo punto installate XCode dal DVD di Snow Leopard e controllate le gemme da reinstallare a 64 bit con lo script http://gist.github.com/178178.

Nel caso in cui abbiate dei problemi con la gemma ruby di mysql reinstallatela con il comando:

    1 sudo env ARCHFLAGS="-arch x86_64" gem install mysql -- --with-mysql-config=/opt/local/lib/mysql5/bin/mysql_config
    2 

Se ottenete il seguente errore:

    1 dyld: lazy symbol binding failed: Symbol not found: _mysql_init
    2   Referenced from: /Library/Ruby/Gems/1.8/gems/mysql-2.8.1/lib/mysql_api.bundle
    3   Expected in: flat namespace
    4 
    5 dyld: Symbol not found: _mysql_init
    6   Referenced from: /Library/Ruby/Gems/1.8/gems/mysql-2.8.1/lib/mysql_api.bundle
    7   Expected in: flat namespace

oppure:

    1 Status: 500 Internal Server Error
    2 uninitialized constant MysqlCompat::MysqlRes

e avete il mysql installato tramite port, ricompilatelo di nuovo a 64 bit con il comando:

sudo port upgrade mysql5

Se trovate altre complicazioni segnalatele pure nei commenti, grazie.