Uso degli helpers - ciclo if else

Buongiorno a tutti, premetto che non sono per niente esperta di rails e
ruby ma sto cominciando da poco a bazzicarlo.
Detto questo, sto facendo un po’ di esperimenti in un progetto che
prevede tra le tante cose, una tabella anagrafica di determinate
personalità storiche. Queste Persone (ho chiamato così la tabella) non
hanno una data di nascita o morte precisa ma un intervallo di date.
Vorrei che fossero visualizzati entrambi gli intervalli se sono stati
inseriti, solo uno dei due se è stato completato solo un campo.
Ho usato un ciclo if else e ho fatto quindi così (dove int_nascita1 e
int_nascita2 sono appunto i due intervalli relativa alla data) :

app/views/index.html.erb

<% @persone.each do |persona| %>

<%= link_to persona.nome, :action =>'show', :id => persona.id %>

<% if persona.int_nascita2.nil? or persona.int_nascita2 == “” %>

<%=h persona.int_nascita1 %> <% else %> <%=h persona.int_nascita1 %> - <%=h persona.int_nascita2 %> <% end %>

resto del codice[…]

Il tutto funziona. Mi hanno però consigliato di spostare i cicli if
dalle views agli helpers in modo da tenere il codice più pulito ma io
non sono riuscita a farlo.

Ho pensato di farlo così, ma non funziona, qualcuno sa dirmi gentilmente
dove sbaglio??

app/views/index.html.erb

<% @persone.each do |persona| %>

<%= link_to persona.nome, :action =>‘show’, :id => persona.id
%> <% hidden_data(persona.int_nascita2.nil?, persona.int_nascita2 == "", persona, persona.int_nascita1) %>

resto del codice[…]

app/helpers/persone_helper.rb

module PersoneHelper
def hidden_data(condition1, condition2, column1, column2)
if condition1 or condition2
Persona.column1
else
Persona.column1 + “-” + Persona.column2
end
end
end

Grazie in anticipo a chiunque abbia voglia di aiutarmi!
paola

Il 24 febbraio 2010 13.10, Paola A. [email protected] ha
scritto:

[…] una tabella anagrafica di determinate
personalità storiche. Queste Persone (ho chiamato così la tabella) non
hanno una data di nascita o morte precisa ma un intervallo di date.
Vorrei che fossero visualizzati entrambi gli intervalli se sono stati
inseriti, solo uno dei due se è stato completato solo un campo.
[…]
Il tutto funziona. Mi hanno però consigliato di spostare i cicli if
dalle views agli helpers in modo da tenere il codice più pulito ma io
non sono riuscita a farlo.

ciao,

Poiché il test nil? e == “” è uno dei più frequenti, rails ha
introdotto un più stringato blank?, che è comodissimo.

Ecco un esempio di come potresti fare:

app/helpers/persone_helper.rb

module PersoneHelper
def valore_o_intervallo_di_nascita persona
if persona.int_nascita2.blank?
h(persona.int_nascita1)
else
“#{h(persona.int_nascita1)}-#{h(persona.int_nascita2)}”
end
end
end

<% @persone.each do |persona| %>

<%= link_to h(persona.nome), :action =>'show', :id => persona.id %> <%= valore_o_intervallo_di_nascita persona %> ...

Ultima considerazione: se stai usando rails nel modo più comodo, cioè
seguendo le varie convenzioni tra cui REST (ad esempio, se usi
scaffold o simili), il link lo puoi scrivere
così:
<%= link_to h(persona.nome), persona %>

Più breve e leggibile.

pietro

Grazie!! Funziona perfettamente!
Mi spiegheresti gentilmente un paio di cose?

il significato dell’h e delle parentesi tonde qui davanti
h(persona.int_nascita1)
e le virgolette, il cancelletto e le parentesi graffe qui davanti
“#{h(persona.int_nascita1)}-#{h(persona.int_nascita2)}”

insomma gli accorgimenti per costruire il tutto, ne ho giusto una vaga
idea.

Grazie ancora!

Il 24 febbraio 2010 18.11, Paola A. [email protected] ha
scritto:

Grazie!! Funziona perfettamente!
Mi spiegheresti gentilmente un paio di cose?

il significato dell’h e delle parentesi tonde qui davanti
h(persona.int_nascita1)

h è un’abbreviazione (un alias) per html_escape:

http://api.rubyonrails.org/classes/ERB/Util.html#M000315

Come dice il nome, fa l’escape dell’html, vale a dire rimpiazza tutti
i caratteri che in html hanno un significato particolare in apposite
sequenze con la loro versione “innocua”.
Ad esempio, < viene trasformato in < e > in >.
Questa è un’operazione importantissima, da effettuare sempre su
tutti i caratteri digitati dall’utente, per impedire il Cross Site
Scripting (anche detto XSS):

In pratica, un utente potrebbe riempire un form con valori tipo:

Così facendo, potrebbe danneggiare gli utenti che accedono alla pagina che mostra quei dati. L'html escape fa sì che la riga precedente venga tradotta in <script type="text/javascript" src="url/di/uno/script/che/fa/cose/brutte.js"&gt Col risultato che il javascript non verrebbe eseguito: un utente che guardasse i dati vedrebbe esattamente la stringa come l'ha inserita l'utente, cioè di nuovo: Anche se sai che la tua applicazione sarà usata solo da pochi fidati, è buona norma usare *sempre* h o equivalenti, perché non si sa mai (ad esempio, magari tra un anno si decide di esporre al pubblico tutta o parte dell'applicazione...). > e le virgolette, il cancelletto e le parentesi graffe qui davanti > "#{h(persona.int_nascita1)}-#{h(persona.int_nascita2)}" Questa è una sintassi di ruby: "#{a}" è equivalente a: a.to_s (to_s trasforma un oggetto in stringa, se non lo è già). Esempio: "#{3 + 2}" dà come risultato "5". pietro

Già che ci sono chiedo un’altra cosa.
Ho una serie di attributi per la visualizzazione delle fonti secondarie:

Elenco fonti secondarie

<% @secondarie.each do |secondaria| %>

  • <%=h secondaria.autore %> (<%=h secondaria.anno_edizione %>) <%=h secondaria.titolo %>, <%=h secondaria.luogo %>, <%=h secondaria.casa_editrice %>

    resto del codice […]

    Sono quasi tutti opzionali, quindi nel momento in cui vado a
    visualizzarli ovviamente se uno è mancante si vede il segno di
    interpunzione senza avere il campo stampato.
    Ho pensato quindi di utilizzare sempre i cicli per stampare quelli
    presenti con virgola annessa, ma inutile dirlo, non ci sono riuscita.

    Ho provato così:

    def bibliografia secondaria
    a = [secondaria.autore, secondaria.anno_edizione, secondaria.titolo]
    a.each do |x|
    “#{h(secondaria.autore)}(#{h(secondaria.anno_edizione}),#{h(secondaria.titolo)}”
    end
    end

    o così:
    def bibliografia secondaria
    a.each do |secondaria.autore, secondaria.anno_edizione,
    secondaria.titolo|
    “#{h(secondaria.autore)}(#{h(secondaria.anno_edizione)}),#{h(secondaria.autore)}”
    end
    end

    più altri tentativi con
    if secondaria.autore.present?

    ma senza arrivare a nulla.
    Avete qualche suggerimento?
    Grazie ancora paola

Grazie!!
paola

Il 26 febbraio 2010 10.53, Paola A. [email protected] ha
scritto:

<%=h secondaria.titolo %>, <%=h secondaria.luogo %>, <%=h
secondaria.casa_editrice %>


resto del codice […]

Sono quasi tutti opzionali, quindi nel momento in cui vado a
visualizzarli ovviamente se uno è mancante si vede il segno di
interpunzione senza avere il campo stampato.

Non ho capito bene: è possibile che ci sia ad esempio autore e titolo
ma non anno_edizione e luogo? Oppure è possibile che ci sia un record
interamente bianco?

Cioè, quali sono i campi che sicuramente non sono vuoti?

pietro

Diciamo che il campo che ci sarà sicuramente sarà quello del titolo, in
effetti potrei anche mettere una validazione su di esso.

Il 26 febbraio 2010 11.15, Paola A. [email protected] ha
scritto:

In realtà la cosa è ancora un pelo più complicata, quello che
effettivamente devo dirgli è:
se c’e l’autore visualizzalo
se c’è l’anno di edizione visualizzalo fra parentesi
se c’è il titolo visualizzalo in corsivo (cioè fra gli ) e dopo
mettici la virgola
se c’e il luogo di edizione visualizzalo e dopo mettici la virgola
se c’è la casa editrice visualizzalo

Parti da questo:

def bibliografia_secondaria secondaria
result = []
result << h(secondaria.autore) unless secondaria.autore.blank?
result << " (#{h secondaria.anno_edizione})" unless
secondaria.anno_edizione.blank?
result << " #{h secondaria.titolo}"
result << “, #{h secondaria.luogo}” unless secondaria.luogo.blank?
result << “, #{h secondaria.casa_editrice}” unless
secondaria.casa_editrice.blank?
result.join ‘’
end

da usare con:

    <% @secondarie.each do |secondaria| %>
  • <%= bibliografia_secondaria secondaria %>
  • <% end %>

E aggiustalo secondo le tue
necessità.

pietro

Si quello che ho postato è l’esperimento con le fonti secondarie, quindi
in linea di massima avranno tutti i campi completati, la stessa cosa
però dovrò farlo con le fonti primarie dove regna l’incertezza. Spesso
può esserci un campo solo completato o due, etc, insomma estremamente
variabile.

Vorrei quindi che venisse fuori una sorta di bibliografia settata
correttamente, ovviamente nei limiti del possibile.

Ho provato anche così:

def bibliografia secondaria
i = [secondaria.autore, secondaria.anno_edizione, secondaria.titolo]
while i.present?
puts “#{h(i)},”
end
end

dato che in realtà prima stavo solo facendo delle prove, senza
effettivamente dirgli “metti la virgola dopo ogni campo presente”.

In realtà la cosa è ancora un pelo più complicata, quello che
effettivamente devo dirgli è:
se c’e l’autore visualizzalo
se c’è l’anno di edizione visualizzalo fra parentesi
se c’è il titolo visualizzalo in corsivo (cioè fra gli ) e dopo
mettici la virgola
se c’e il luogo di edizione visualizzalo e dopo mettici la virgola
se c’è la casa editrice visualizzalo

spero di essere stata più chiara!
grazie ancora!

Intanto ringraziamenti infiniti…poi mi spiegheresti qualcosa così
imparo (se hai voglia e tempo)?

Parti da questo:

def bibliografia_secondaria secondaria
bibliografia_secondaria (nome del modulo), secondaria cos’è? cosa gli
dice di recuperare? i campi della tabella “secondaria”?

result = []

questo crea un array con i “risultati delle operazioni”?

result << h(secondaria.autore) unless secondaria.autore.blank?

<< cos’è? restituisce il valore dopo averlo processato?

al posto di unless secondaria.autore.blank? potevo usare anche if
secondaria.autore.present? ?

result.join ''

join?

paola

Il 26 febbraio 2010 14.14, Paola A. [email protected] ha
scritto:

def bibliografia_secondaria secondaria
bibliografia_secondaria (nome del modulo), secondaria cos’è? cosa gli
dice di recuperare? i campi della tabella “secondaria”?

Qui definisco una funzione, bibliografia_secondaria, e dico che ha un
parametro, che in questo caso ho chiamato secondaria ma che avrei
potuto chiamare anche a, oppure la_vispa_teresa, e sarebbe stata la
stessa cosa. Naturalmente nel corpo della funzione avrei poi dovuto
usare a oppure la_vispa_teresa.

Quello che poi conta è ciò che gli viene passato; nel mio esempio gli
viene passata la variabile “secondaria”, che esiste solo all’interno
del blocco passato a each, e in quel contesto contiene un elemento
dell’array @secondarie:

<% @secondarie.each do |secondaria| %>

  • <%= bibliografia_secondaria secondaria %>
  • <% end %>
    result = []
    

    questo crea un array con i “risultati delle operazioni”?

    Questo crea un array che, casualmente, ha il nome result, ma anche qui
    avrei potuto scegliere un nome diverso, come un_nome_diverso; è però
    convenzione chiamare result la variabile che conterrà i dati da
    restituire.

    result << h(secondaria.autore) unless secondaria.autore.blank?
    

    << cos’è? restituisce il valore dopo averlo processato?

    << è un metodo della classe Array, che aggiunge ciò il parametro o i
    parametri forniti alla fine dell’array ed ha come valore di ritorno
    l’array stesso.

    Ti consiglio la lettura della documentazione della classe Array, e in
    particolare di questo metodo:
    http://ruby-doc.org/core/classes/Array.html#M002167

    al posto di unless secondaria.autore.blank? potevo usare anche if
    secondaria.autore.present? ?

    Sì.

    result.join ''
    

    join?

    join è un altro metodo della classe Array:

    http://ruby-doc.org/core/classes/Array.html#M002182

    Quello che fa è restituire una stringa contenente gli elementi
    dell’array trasformati in stringa, separati dall’eventuale separatore
    (che se manca è stringa vuota, come quella che gli passo io, quindi in
    effetti avrei potuto scrivere
    result.join
    e sarebbe stato uguale).

    Esempio:

    a = [“oggi”, “ieri”, “domani”]
    a.join " ma anche "
    => “oggi ma anche ieri ma anche domani”

    pietro