29 Mar
matte

matte il 29 March 2006 parla di Rails Snippet

in_place_editor multiplo

Oggi, mentre cercavo di utilizzare in_place_editor mi sono confrontato con alcuni problemi:

  • L’utilizzo di in_place_editor per la modifica di una collezione di record.
  • La validazione del modello durante il salvataggio del record.

Vediamo come risolvere questi due punti, assumendo di voler utilizzare in_place_editor con una tabella di nome categories e voler cambiare il campo name.

Per quanto riguarda il primo punto dobbiamo creare un partial di nome _category.rhtml con il seguente codice:

    1 <% @category = category %>
    2 <p><%= in_place_editor_field :category, name %></p>

dove category è la variabile passata al partial dalla vista da cui è richiamato. Il tip sta nel creare una nuova variabile @category che andrà ad utilizzare l’helper in_place_editor_field.

Il secondo punto si può risolvere facendo un override della funzione creata da in_place_editor_for all’interno del controllore. Questo perché in_place_editor salva le modifiche saltando la validazione dell’attributo. La nuova funzione sarà:

    1 def set_category_name
    2   @cat = Category.find(params[:id])
    3   previous_name = @cat.name
    4   @cat.name = params[:value]
    5   @cat.name = previous_name unless @cat.save
    6   render :text =>  @cat.name
    7 end

In questo modo se il salvataggio non va a buon fine non sarà effettuata alcuna modifica sul database. Inoltre, creando manualmente la funzione setcategoryname è possibile togliere dal controllore la riga

    1 in_place_editor_for :category, :name

Per risolvere il secondo punto è possibile anche creare un file (ajax_helper.rb) da inserire nella cartella lib in modo da effettuare l’override della funzione creata a runtime genericamente, in modo da non dover riscrivere il codice per ogni in_place_editor che si andrà a creare. Questo è stato proposto nel seguente post. Purtroppo nel codice è presente un bug, quindi ve lo scrivo corretto:

    1 module AjaxHelper
    2 
    3   def self.append_features(base)
    4     base.extend(ClassMethods)
    5   end
    6 
    7   module ClassMethods
    8     #The default Rails helpers do not check for validation
    9     #before saving the attributes
   10     #this function provides a way of safely editing 
   11     #a models attribute without destroying data integrity
   12     def ajax_edit_field(model_name, model_attribute)
   13       class_eval %{
   14         def set_#{model_name}_#{model_attribute}
   15           model_instance = \
   16           #{model_name.to_s.camelize}.find(params[:id])
   17           old_#{model_attribute.to_s}_value = \
   18           model_instance.#{model_attribute.to_s}
   19           model_instance.#{model_attribute.to_s} = \
   20           params[:value]
   21           model_instance.#{model_attribute.to_s} = \
   22           old_#{model_attribute.to_s}_value  \
   23           unless model_instance.save
   24             render :text => model_instance.#{model_attribute.to_s}
   25           end
   26         }
   27       end
   28     end
   29   end

Dovrete a questo punto inserire nel controllore la seguente inclusione:

    1 include AjaxHelper

e richiamare nel controllore

    1 ajax_edit_field :category, :name

al posto di

    1 in_place_editor_for :category, :name

Technorati Tags: , ajax

2 Commenti a “in_place_editor multiplo”

  1. Federico il 30 March 2006 alle 11:29 dice:

    Ti ringrazio per questo post, sto proprio lavorando con in_place_editor ed avevo notato lo stesso problema… :)

  2. matte il 30 March 2006 alle 11:33 dice:

    Ci mancherebbe! è bello risolvere un problema e poter condividere la soluzione soprattutto con una comunità come quella intorno al Rails.

Scrivi un commento