2009-12-16 3 views
0

Je suis en train de créer un tas de méthodes d'aide dynamiques comme celles-ci:créer des méthodes d'aide dynamique dans les rails

show_admin_sidebar 
show_posts_sidebar 
show_users_sidebar 

Jusqu'à présent, j'ai dans mon fichier helper.rb:

#spits out a partial 
def show_sidebar(name, show_sidebar = true) 
    @content_for_sidebar = render :partial => "partials/#{name}"      
    @show_sidebar = show_sidebar 
end 

def show_sidebar? 
    @show_sidebar 
end 

En mon dossier de mise en page de l'application que j'ai ceci: (NB - J'utilise HAML):

- if show_sidebar? 
    = yield(:sidebar) 

cela me permet de dire ce qui suit dans ma vi ews:

- show_sidebar(:foo) 
- show_sidebar(:bar) 

Et ceci rend le partiel désiré.

Le problème avec ceci est que je ne peux ajouter qu'une seule barre latérale par page. Donc, je me dis que j'ai besoin de méthodes dynamiques comme: show_admin_sidebar, show_foo_sidebar.

J'ai donc essayé de le faire:

def show_#{name}_sidebar(show_sidebar = true) 
@name = name 
@content_for_#{@name}_sidebar = render :partial => "partials/#{@name}"      
    @show_sidebar = show_sidebar 
end 

puis dans ma mise en page:

- if show_sidebar? 
    = yield("{@name}_sidebar") 

Mais rails n'aime pas du tout.

J'ai essayé presque tout ce que je peux penser dans mon fichier d'aide et rien ne fonctionne. La raison pour laquelle j'utilise des méthodes auxiliaires est parce que je veux que mon contenu div soit 100% de largeur de page à moins qu'une barre latérale ne soit présente, auquel cas le contenu principal passe dans une div plus petite et le contenu de la barre latérale possèdent ..

Si je ne peux pas obtenir ce travail, alors je peux facilement résoudre le problème en ajoutant simplement les partials manuellement, mais je voudrais obtenir ma tête autour de cette ....

Quelqu'un at-il une expérience avec ce genre de chose?

Répondre

2

Voici une solution pour vous, mais je ne dirais pas trop metaprogramming:

#Add the following snippet to the proper helper module: 
['admin','user','whatever'].each do |name| 
    class_eval{ 
    "def show_#{name}_sidebar(show_sidebar = true) 
     @name = #{name} 
     @content_for_#{@name}_sidebar = render :partial => 'partials/#{@name}'      
     @show_sidebar = show_sidebar 
    end" 
    } 
end 
+0

THaNKYOU tellement. C'est une nouvelle étape pour moi, c'est vraiment une aide précieuse. Je pense que je peux trouver mon chemin à partir d'ici. regds steve – stephenmurdoch

0

montrer def _ # {name} _sidebar (show_sidebar = true)

Cela ne ressemble pas à Ruby valide pour moi. Est-ce que vous l'analysez et l'évaluez vous-même ou que vous jetez juste cela dans le fichier et que vous vous attendez à ce qu'il fonctionne?

+1

merci pour votre réponse, oui, je suis juste un peu en espérant que cela fonctionnerait. pas sûr d'analyser et d'évaluer pour être honnête. Id comme somethign qui fonctionne de manière similaire aux méthodes dynamiques find_by. J'essaie de découvrir comment ils fonctionnent, puis éventuellement réutiliser la technique. se penchera sur l'analyse et l'évaluation comme vous le suggérez. – stephenmurdoch

+0

Alors votre seul vrai problème est que vous n'avez pas réellement appris Ruby. http://ruby-doc.org/core/classes/Kernel.html#M005925 –

+0

ha ha! vrai. Merci pour le lien. tout le monde doit commencer quelque part. – stephenmurdoch

4

L'approche entière à c'était bizarrement excessivement complexe, n'a pas suivi Rails conventions du tout, ni faire la moindre peu de sens, et honte aux répondants précédents pour permettre cette approche au lieu de l'aider à simplifier. Mes excuses pour avoir 13 mois de retard avec la réponse. Votre contrôleur doit décider si une barre latérale doit être affichée ou non, et définir une variable d'instance @side_bar_name sur une chaîne de noms nil ou sidebar. Puis quelque part dans le code de la vue partagée, probablement views/layouts/application.html.Erb, vous auriez quelque chose d'aussi simple que cela:

<% if @side_bar_name %> 
<%= render :partial => "partials/#{@side_bar_name}" %> 
<% end %> 

Ou mieux encore:

<%= render(:partial => "partials/#{@side_bar_name}") if @side_bar_name %> 

Si vous souhaitez utiliser une aide (ce qui est une mauvaise idée pour garder votre code DRY et lisible) il serait fondamentalement le même code, juste déplacé dans l'assistant.

<%= side_bar_helper %> 

def side_bar_helper 
    render(:partial => "partials/#{@side_bar_name}") if @side_bar_name 
end 

Ce que fait le contrôleur vous appartient. Il serait sans doute faire quelque chose comme ceci:

if session[:show_side_bar] 
    # maybe use cookies instead of session, or store user preference in a database 
    @side_bar_name = session[:side_bar_name] 
end 
Questions connexes