The Caribbean Weblog

"This blog is continuing @ http://christophemaximin.com "

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

jeudi 23 novembre 2006

Ruby on rails : Écrire ses input text (encore plus) simplement

RubyLogo Quand j'écris un formulaire, j'ai pris l'habitude d'écrire mes entrées de texte[1] autour du shéma suivant :

<p><label>%s: %s</label></p>

Ainsi, pour demander un "descriptif de la location", je suis contraint d'écrire ceci [2]:

<p><label>Descriptif de la location: <%= text_field "form", "descriptif_de_la_location" %></label></p>

... ce qui enfreint la règle du Don't Repeat Yourself, et qui est fatiguant tout simplement, lorsque l'on est confronté à plus de 5 inputs du genre.

J'ai donc rajouté ceci à mes helpers (dans app/helpers/application_helper.rb) :

 def winput(input_name, options={})
   pre_options = {
     :markup_scheme => "<p><label>%s: %s</label></p>",
     :text => input_name.capitalize.gsub('_',' '),
     :form_name => 'form',
     :options => {}
   }
   o = pre_options.merge(options)
   markup = text_field o[:form_name], input_name, o[:options]
   return sprintf(o[:markup_scheme], o[:text], markup)
 end

Cet helper me permet de faire exactement la même chose qu'en haut en écrivant seulement :

<%= winput "description_de_la_location" %>

Comme vous le constatez, vous pouvez changer le nom du formulaire, le "markup scheme" (j'ai rien trouvé de mieux sur le coup), et le texte qui va avec. Aussi, les options habituelles du text_field peuvent être aussi passées par le symbol du même nom. Exemple :

<%= winput 'login', :form => 'user', :text => 'Desired login', :options => {:size => 30} %>

... ce qui donnera :

<p><label>Desired login: <input id="user_login" name="user[login]" size="30" type="text" /></label></p>

EDIT (25/11/06) : Je vais vous épargner le code ruby correspondant, mais j'ai un peu amélioré le code afin (entre autres) d'arriver à ce que ceci :

 <% $form_name = 'location' %>
 <%= wtextarea 'descriptif_de_la_location' %>
 <%= wtextarea_f 'situation_geographique' %>
 <%= wtextarea 'tarifs' %>
 <%= winput 'a_partir_de', :text => 'Votre plus bas tarif toutes périodes confondues (en euro)', :after => '€' %>
 <%= radios = radio_button('location', 'animaux_admis', 1, :checked => 'true') + "Oui " + radio_button('location', 'animaux_admis', 0) + "Non"
 markup_scheme 'Les animaux sont-ils admis ?', radios %>

... me sorte cela :

 <p><label>Descriptif de la location :<br /> <textarea cols="40" id="location_descriptif_de_la_location" name="location[descriptif_de_la_location]" rows="20"></textarea></label></p>
 <p><label>Situation geographique (facultatif):<br /> <textarea cols="40" id="location_situation_geographique" name="location[situation_geographique]" rows="20"></textarea></label></p>
 <p><label>Tarifs :<br /> <textarea cols="40" id="location_tarifs" name="location[tarifs]" rows="20"></textarea></label></p>
 <p><label>Votre plus bas tarif toutes périodes confondues (en euro) : <input id="location_a_partir_de" name="location[a_partir_de]" size="30" type="text" value="0" />€</label></p>
 <p><label>Les animaux sont-ils admis ? : <input checked="true" id="location_animaux_admis_1" name="location[animaux_admis]" type="radio" value="1" />Oui <input id="location_animaux_admis_0" name="location[animaux_admis]" type="radio" value="0" />Non</label></p>

L'idée de départ étant d'adapter la méthode à vos besoins, et celon ce qui vous parait pratique. Perso, j'aime.

Notes

[1] Avec le helper text_field 99% du temps

[2] Petites précisions pour les non-utilisateurs de rails : le fait de donner un nom au formulaire dans chaque champ permet de faire la chose suivante newloc = Location.new(params[:form]) pour précharger directement la valeur des champs liés au formulaire, et après rajout d'autres valeurs (newloc.ip_adress = request.remote_ip par exemple), de terminer par un joli newloc.save pour exécuter la requete SQL qui va bien.

mercredi 22 novembre 2006

Apache : Stupid htaccess Tricks

(via koke's weblog)

Pas de blabla, que du bon : http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/

samedi 18 novembre 2006

Ruby on Rails : Gestion de l'Intégrité référentielle dans les migrations

Rails (ActiveRecord plus précisement) intègre un "système de versionning de structure de base de donnée" (expression trouvée à l'instant[1]), communément appelé Migrations, dont tout le monde chante les louanges, ce qui est assez justifié, bien que j'ai été moi-même assez septique sur son utilité/charme. Lisez les pages suivantes pour en comprendre le principe et le fonctionnement :
http://wiki.rubyonrails.com/rails/pages/UsingMigrations
http://wiki.rubyonrails.com/rails/pages/UnderstandingMigrations
http://rubyonrails.com/rails/classes/ActiveRecord/Migration.html

Malheureusement, les contraintes ne sont pas encore supportés avec cette syntaxe, alors vous devez les ajouter à la main, en SQL pur (execute "alter table users add constraint fk_users_post_id foreign key (post_id) references posts(id)")

Si vous avez suivi le principe des migrations, vous comprendrez que l'on peut en faire une seulement pour rajouter un champ avec une foreign_key, ce qui implique qu'elle soit droppée au self.down. Ça fait beaucoup.

Il est donc recommandé d'utiliser un helper pour gérer tout ça :
Séb Box : http://seb.box.re/articles/2006/07/29/foreign-key-and-rails-migration

Notes

[1] le fait qu'elle existait ou non avant m'importe peu

lundi 13 novembre 2006

Un truc (de plus) que j'aime en ruby

class Ticket
  def price=(amount)
    if [Fixnum,Float].include? amount.class
      @price = amount
    else
      puts "The price seems to be malformed"
    end
  end
end

Ce qui à pour incidence ceci (irb --simple-prompt powered):

>> Ticket.new.price = 22
=> 22
>> Ticket.new.price = 'prix'
The price seems to be malformed
=> "prix"

Petite explication pour ceux qui n'ont pas compris ce qui est intéressant :
Cet exemple montre que ruby permet de tester de façon transparente l'assignement d'une valeur à une méthode (qui se trouve dans un objet instancié dans le cas présent). Ce code teste si amount est un nombre (entier ou flottant), et si oui, assigne cette valeur à price, ou affiche un message d'erreur. [1] Toute l'astuce est dans la définition de la méthode price : def price=(amount) et du signe = qui n'est pas annodin. C'est lui qui permet de faire passer pour assignement banal de valeur, à l'appel d'une méthode, qui est bien price= et non pas price.
De plus, Ruby gère le fait que vous mettiez ou non un espace entre price et = quand vous voulez lui assigner une valeur, donc :

Ticket.new.price = 22
# est strictement équivalent à 
Ticket.new.price= 22

Notes

[1] if [Fixnum,Float].include? amount.class signifie "si le tableau qui contient les constantes Fixnum et Float inclu la valeur 'classe de amount'". Étant donné que tout est une objet en ruby, un nombre est soit un entier (Fixnum), soit un flottant (Float), ce que vous pouvez vérifier par vous même dans irb en tappant 0.class. Voir aussi Test de valeurs, PHP & Ruby

Pages: