2009-05-29 5 views
0

J'essaie d'écrire ma première action de contrôleur personnalisé et je cours dans un NoMethodError.Transmettre des données via la variable d'instance du contrôleur à la vue, qu'est-ce que je fais de mal?

Le scénario: PostsController, avec l'échafaudage standard 7 actions génère.

Je souhaite que la page d'index affiche un seul article au lieu d'afficher une liste d'entre eux. Chaque message a une case "visible". J'ai créé un named_scope appelé visible dans le modèle Post avec:

named_scope :visible, :conditions => ["visible =?", true] 

et l'a appliqué avec .last à l'action d'index dans mon contrôleur:

def index 
    @post = Post.visible.last 
    (format stuff) 
end 

Edité mon avis d'index pour enlever le itérer une partie de tableau ainsi il montre juste @post.title, etc. Donc maintenant mon index affiche juste le dernier enregistrement dans la table de poteaux avec vrai sur visible.

Je veux ensuite créer un tous les messages page Archive, qui montre tous quelle que soit la visibilité, donc je créé une nouvelle action du contrôleur:

(modifié pour plus de clarté)

def archives 
    render :layout => 'posts' 
    @posts = Post.find(:all) 

    respond_to do |format| 
    format.html 
    format.xml { render :xml => @posts } 
    end 
end 

créé une nouvelle route nommée:

map.archives 'posts/archives', :controller => 'posts', :action => 'archives' 

et une vue nommée archives.html.erb sous les vues/messages.

Archives.html.erb ressemble exactement le modèle standard index.html.erb cet échafaudage crée, avec un

<% for post in @posts %> 
    <tr> 
    <td><%=h post.title %></td> 
    ... 
    </tr> 
<% end %> 

Quand je regarde cette page dans mon navigateur, je reçois une erreur de

NoMethodError dans les messages archives #

vous avez un objet nul quand on ne s'y attendait pas, vous pourriez avoir prévu un isntance de tableau, l'erreur est survenue lors de l'évaluation nil.each,

pointe sur la ligne dans la vue (app/views/messages/archives.html.erb) qui dit

<% for post in @posts %> 

donc je crois comprendre que les données de la variable d'instance dans l'action du contrôleur archives ISN ne passant pas dans la vue, donc au lieu d'un tableau de messages, je n'ai rien. Je cherche une raison pourquoi, et ce que je fais mal.

(Bien sûr, si je mets

<% @posts = Post.find(:all) %> 

avant la

<% for post in @posts %> 

dans la vue, il fonctionne très bien, mais je sais que ce n'est pas ce que je devrais faire.

Toute aide, liens vers des tutoriels pour me redresser, etc. est très appréciée.

(. Je doute qu'il compte avec quelque chose ce simple, mais j'utilise Rails 2.2.2 et Ruby 1.8.6)

+0

Il est difficile de dire à partir de vos extraits. Pourriez-vous ajouter le code du contrôleur et de la vue au bas de votre question? – eggdrop

+0

Au moins remplir l'action du contrôleur afin que nous puissions nous assurer qu'il ne se passe rien là-bas qui essuie accidentellement @posts. –

+0

Désolé pour le retard dans la réponse. J'ai limité le problème à un peu j'ai oublié d'inclure (bien sûr, désolé) -Je veux rendre en utilisant une mise en page différente pour cette action spécifique (archives), donc j'ai un rendu: layout => 'archives', avec un fichier archives.html.erb dans/views/layouts. Si je supprime cette ligne, je ne reçois pas l'erreur. J'ai aussi essayé 'render: action => 'archives',: layout => 'archives''. N'est-ce pas la bonne façon d'assigner une mise en page spécifique à une action du contrôleur? – blupt

Répondre

2

Ceci est correct:

respond_to do |format| 
    format.html { render :layout => 'posts' } 
    format.xml { render :xml => @posts } 
    end 
end 

@posts était non reconnu par la vue car il a été instancié après avoir rendu la vue. 'Render' devrait être la dernière ligne exécutée dans une action.

Questions connexes