2011-09-13 2 views
0

J'ai une vue où j'essaie de vérifier si un champ dans une table est présent, et si c'est le cas, imprimez juste ce champ. Sinon, il devrait imprimer le texte: "(aucun)". À mon avis je:Comment mettre la logique dans Rails helper?

<%= list_fields(feed) %> 

Et dans mon dossier d'aide je:

def list_fields(feed) 
     feed.xml_fields.each do |field| 
      if field.tags? 
       field.tags 
      else 
       puts "(none)" 
      end 
     end 
    end 

En ce moment, cette affiche toute la ligne de table pour chaque objet champ si elle a des balises, et « [] » s'il n'a pas de tags Je veux juste que l'entrée des tags individuels soit affichée ou "(none)". Qu'est-ce qui me manque dans mon assistant?

Répondre

2

Vous avez deux problèmes. Le premier est que votre assistant ne renvoie pas la valeur qui pourrait être incluse dans la vue par la construction <%= ... %>.

L'appel .each retourne l'objet sur lequel il a été appelé, dans ce cas, il serait feed.xml_fields, et il ne retourne pas les valeurs individuelles calculées par le bloc.

Le deuxième problème est que puts dans Rails ne place pas le texte dans la vue rendue - ce n'est pas PHP.

Je ne suis pas très confiant que la sortie exacte que vous attendez, mais si vous voulez retourner le premier « champ » qui a « balises », alors vous pouvez le faire:

def list_fields(feed) 
    f = feed.xml_fields.detect {|field| field.tags? } 
    f ? f.tags : "(none)" 
end 

Si vous voulez la liste toutes les balises et de retourner la chaîne « (aucun) », s'il n'y a pas de balises, puis utilisez quelque chose comme ceci:

def list_fields(feed) 
    f = feed.xml_fields.select {|field| field.tags? }.map {|field| field.tags } 
    f.empty? ? "(none)" : f.join(", ") 
end 

Si vous souhaitez rejoindre les champs avec quelques balises HTML, comme un <br/>, puis utilisez ceci:

def list_fields(feed) 
    f = feed.xml_fields.select {|field| field.tags? }.map {|field| h(field.tags) } 
    f.empty? ? "(none)" : f.join("<br/>").html_safe 
end 

Notez qu'il existe deux changements: les valeurs sont tags individuelles se sont échappés par la fonction h, puis la chaîne joint est marquée comme étant déjà aseptisé. Dans ce cas, la vue n'échappe pas à nouveau à la chaîne.

Si vous voulez vraiment utiliser quelque chose comme puts dans les vues ou les aides, alors vous pouvez lire sur la méthode concat.

+0

Merci, j'essayais d'accomplir la dernière de vos suggestions. Je suis un peu confus sur la syntaxe. Avec ce 'f.join (", ")', je veux réellement les joindre de sorte que chacun imprime sur une nouvelle ligne. J'ai essayé à la fois 'f.join (" \ n ")' et 'f.join ("
")' en vain. – Paul

+1

J'ai mis à jour la réponse. Le dernier exemple montre comment placer des balises HTML dans la chaîne retournée par helper. – Arsen7

+0

J'ai compris, merci! – Paul

0

Renvoyez les chaînes de votre assistant au lieu d'utiliser puts. Je ne sais pas quel format est field.tags, mais je suppose que c'est un tableau. Formatez la chaîne comme vous le voulez et renvoyez-la simplement de l'assistant.

Quelque chose comme:

def list_fields(feed) 
    feed.xml_fields.each do |field| 
    if field.tags? 
     "some string" 
    else 
     "(none)" 
    end 
    end 
end 
+0

'field.tags' est une chaîne. Même en mettant juste "une certaine chaîne" après le conditionnel ne change pas ce qui est réellement imprimé à l'écran. C'est toujours tout le tableau 'field', plutôt que simplement' field.tags'. – Paul

+0

oh, derp, car 'each' retourne' feed.xml_fields'. Définissez une variable et renvoyez-la à la fin. – x1a4

1

Vous devez changer votre fonction de telle manière:

def list_fields(feed) 
    feed.xml_fields.each do |field| 
     if field.tags? 
      return field.tags 
     else 
      return "(none)" 
     end 
    end 
end 

Il y a 2 changements:

  • Non mis dans l'aide
  • revenir de la boucle. Le résultat d'un each -loop est le tableau lui-même, donc à la fin, il sera quand même retourné dans votre version.

Je ne comprends pas pourquoi vous faites la boucle.