On se tutoie ?

Aller au contenu | Aller au menu | Aller à la recherche

Mot-clé - activerecord

Fil des billets - Fil des commentaires

mardi, janvier 12 2010

I18n et formulaires imbriqués en rails

En rails 2.3.4 je trouve le comportement du error_messages un peu surprenant avec les formulaires imbriqués.

class Person < ActiveRecord::Base
  accepts_nested_attributes_for :address, :allow_destroy => true
end
class Person < ActiveRecord::Base
  validates_presence_of :label
end
<% form_for(@person) do |f| -%>
  <% f.fields_for :address do |address| %>
    <p>
      <%= address.label :label %>
      <%= address.text_field :label %>
    </p>
  <% end -%>
<% end -%>

D'après http://weblog.rubyonrails.org/2009/1/26/nested-model-forms, les erreurs sont recopiées dans l'objet parent. Ils disent que c'est sujet à changement mais apparement c'est toujours le cas. En créant les objets depuis la console:

>> p  = Person.new
>> p.build_address
>> p.save
>> p.errors
=>
#<ActiveRecord::Errors:0x102d94560 @errors={"address_label"=>[#<ActiveRecord::Error:0x102d7be48 …

Du coup dans mon fichier de traduction je mets logiquement:

person:
  address_label: "foo"

Perdu ! En maintant les mains dans le cambouis vendor/rails je suis remonté jusqu'à generate_full_message qui se base en fait sur la classe de base de l'objet (imbriqué ou non). Du coup il va chercher dans:

address:
  address_label: "foo"

C'est pas vraiment logique, surtout que dans 99% des cas on a déjà la traduction:

address:
  label: "foo"

Ce serait cool s'il pouvait aller le chercher là.
Ah et interdiction de répondre t-as-qu-a-faire-un-patch :-)

mercredi, septembre 17 2008

Accèder à une base MS SQL en ruby sous linux, avec et sans ActiveRecord

Pré-requis

Cette procédure a été testé sous une debian lenny avec un kernel 2.6.18 (et sous OSX Leopard 10.5.4).
L'objectif est donc d'accéder à une base de données Microsoft SQL Server depuis un script ruby sous GNU / Linux.

Installation des packages

L'idée est de communiquer avec la base MS SQL par le biais des librairies FreeTDS et de l'API ODBC.

On commence par installer les packages nécessaires :

aptitude install unixodbc
aptitude install unixodbc-dev
aptitude install sqsh

Il est possible d'installer freetds par aptitude (install freetds-dev qui installe common) mais dans mon cas il manquait le fichier libtdsodbc.so.
Je l'ai donc installé depuis les sources :

wget ftp://ftp.ibiblio.org/pub/Linux/ALPHA/freetds/stable/freetds-stable.tgz
tar xzvf freetds-stable.tgz
cd freetds-0.82
./configure && make && sudo make install

Il faut maintenant définir quelques variables d'environnement définisant les emplacements des fichiers de configuration.
Soit dans le /etc/profile pour que tous les utilisateurs y ait accès, soit dans le .bashrc uniquement pour l'utilisateur courant :

export ODBCINI=/etc/odbc.ini
export ODBCSYSINI=/etc
export FREETDSCONF=/etc/freetds/freetds.conf

Rechargement de la configuration :

$ source /etc/profile

Configuration de la datasource

Dans le /etc/freetds/freetds.conf :

[MY_DSN]
	host = IP du serveur
	port = 1433
	tds version = 7.0

MyDSN représente le nom de la datasource, on peut y mettre le nom souhaité. On teste la connexion au datasource :

$ sqsh -S MY_DSN -U user -P password

Si tout se passe tu atteris sur un prompt de type :

1>

Il nous faut maintenant indiquer à ODBC d'utiliser FreeTDS :

$ vim /etc/odbc.ini
 
[MY_DSN]
Driver          = FreeTDS
Description     = ODBC connection via FreeTDS
Trace           = No
Servername      = MY_DSN
Database        = YOUR_ACTUAL_DB_NAME
$ vim /etc/odbcinst.ini
 
[FreeTDS]
Description     = TDS driver (Sybase/MS SQL)
Driver          = /usr/local/lib/libtdsodbc.so
FileUsage       = 1

On peut maintenant tester l'accès au datasource par le biais de isql, qui permet l'envoi de requêtes SQL sur le serveur :

$ isql MY_DSN user password
SQL> select top 10 * from users (pas de limit)

Note : La close top agit de la même façon que la close limit pour une base de données MySQL.

Accéder aux données MS SQL depuis ruby, sans ActiveRecord

Nous allons utiliser l'interface d'accès aux données DBI en utilisant le driver ODBC.

Il existe maintenant une gem pour ruby dbi :

# gem install dbi

Faisons un premier essai depuis un shell ruby :

$ irb

require 'rubygems'
require 'dbi'

DBI.connect('dbi:odbc:MY_DSN', login, password)
=> Unable to load driver 'odbc'

DBI ne parvient pas à charger le driver odbc. Actuellement odbc est installé sur notre machine mais il n'y a pas d'extension pour dialoguer avec.

On installe donc la librairie ODBC pour ruby :

$ wget http://www.ch-werner.de/rubyodbc/ruby-odbc-0.9995.tar.gz
$ tar zvxf ruby-odbc-0.9995.tar.gz
$ cd ruby-odbc-0.9995/
$ ruby extconf.rb
$ make
# make install

On installe le driver ODBC pour ruby dbi qui utilise odbc.so installé ci dessus :

# gem install dbd-odbc

Désormais le code testé ci dessus fonctionne.
Note : Pas besoin de require 'odbc', dbi inclus automagiquement les drivers présents.

Il est maintenant possible de faire des requêtes manuelles sans passer par AR.
Des exemples sont disponibles sur la doc officielle de ruby-dbi.

Accéder aux données MS SQL depuis ruby, avec ActiveRecord

Il faut utiliser l'adapter odbc, qui n'est plus inclus de base avec Rails :

# gem install activerecord-odbc-adapter

Une fois effectué, la syntaxe pour établir une connection est la suivante :

ActiveRecord::Base.establish_connection({ :adapter => 'odbc', :dsn => 'MY_DSN', :username => 'user', :password => 'password'})

Note : Ce tutoriel fonctionne sous OSX. Sous Leopard, les fichiers de conf odbc (odbc.ini, odbcinst.ini) doivent se situer dans/Library/ODBC.
Les packages à installer peuvent s'installer avec les port ou être directement compilés.