2010-04-15 1 views
0

J'ai reçu beaucoup d'aide de KandadaBoggu sur ma dernière question et je vous en suis très reconnaissant. Comme nous étions enterrés dans les commentaires, je voulais sortir cette partie. J'essaie de créer une fonctionnalité d'étiquette sur le blog de rails que je suis en train de développer. La relation est Post has_many: tags et Tag belongs_to: post. L'ajout et la suppression de tags dans les publications fonctionnent très bien.link_to paramètre de dépassement et problème d'affichage - caractéristique d'étiquette - Ruby on Rails

Dans mon /view/posts/index.html.erb j'ai une section appelée tags où j'interroge avec succès la table Tags, les regroupant et affichant le nombre à côté du tag_name (comme une note de côté, j'ai appelé par erreur la colonne contenant le nom du tag, 'tag_name' au lieu de simplement 'name' comme je devrais l'avoir). De plus, l'affichage de ces groupes est un lien référençant la méthode d'index dans PostsController. C'est là que le problème est. Lorsque vous accédez à/posts, vous obtenez une erreur car aucun paramètre n'est transmis (sans cliquer sur le lien du groupe de variables). J'ai le .empty? là-bas, donc pas sûr de ce qui ne va pas ici. Voici l'erreur et le code:

Erreur

You have a nil object when you didn't expect it! 
You might have expected an instance of Array. 
The error occurred while evaluating nil.empty? 

/views/posts/index.html.erb

<% @tag_counts.each do |tag_name, tag_count| %> 
      <tr> 
       <td><%= link_to(tag_name, posts_path(:tag_name => tag_name)) %></td> 
       <td>(<%=tag_count%>)</td> 
      </tr> 
     <% end %> 

PostsController

def index 
    @tag_counts = Tag.count(:group => :tag_name, :order => 'updated_at DESC', :limit => 10) 
    @posts=Post.all(:joins => :tags,:conditions=>(params[:tag_name].empty? ? {}: 
        { :tags => { :tag_name => params[:tag_name] }} 
        ) 
       ) 

    respond_to do |format| 
     format.html # index.html.erb 
     format.xml { render :xml => @posts } 
     format.json { render :json => @posts } 
     format.atom 
    end 
    end 

Répondre

0

Quand je vous ai donné la solution, je l'avais oublié le fait que j'avais singe patché ma Nil classe avec une méthode empty?. C'est la raison pour laquelle cela ne fonctionne pas pour vous.

Changer le code comme suit:

conditions, joins = {}, nil 
unless(params[:tag_name] || "").empty? 
    conditions = ["tags.tag_name = ? ", params[:tag_name]] 
    joins = :tags 
end 
@posts=Post.all(:joins => joins, :conditions=> conditions) 

Edit 1

Le code ci-dessus effectue empty contrôle au lieu de nil chèque. Je fais toujours une pratique pour effectuer une vérification vide pour les paramètres de requête. Cela couvre les cas où l'action est invoquée à partir d'un formulaire de recherche. Dans de tels cas, tag_name ne sera pas nul mais une chaîne vide.

Edition 2

correction d'un problème de ligne multiple.

Edit 3

Je fixe les postes aucun problème d'exposition lorsque les noms de balises sont présents.

Modifier 4

Pour obtenir le nombre dans l'ordre DESC retirer la clause order de votre appel count.

@tag_counts = Tag.count(:group => :tag_name, :limit => 10) 

La méthode count renvoie une table de hachage commandé triés par comptage. Vous avez modifié l'ordre de tri par défaut en ajoutant la clause order.

+0

Merci encore pour toute l'aide. Le seul code des 4 blocs donnés ci-dessus que je travaille est le second jeu posté par BaroqueBobcat mais il affiche le message dans l'index plusieurs fois. En fait, le nombre de fois qu'il est affiché est directement corrélé au nombre d'étiquettes que le poste a. Des idées sur la façon de résoudre ce problème? – bgadoci

+0

juste pour clarifier, il ne fait que répéter dans la vue d'index, pas quand vous passez le paramètre en cliquant sur le groupe de balises. – bgadoci

+0

J'ai mis à jour la réponse. Le correctif utilisera des jointures uniquement lorsque tag_name est présent. –

0

ici où vous appelez empty? , si params[:tag_name] est nul, cela augmentera l'erreur que vous voyez.

@posts=Post.all(:joins => :tags,:conditions=>(params[:tag_name].empty? ? {}: 
        { :tags => { :tag_name => params[:tag_name] }} 
        ) 
       ) 

Si vous venez de soins si elle est nulle ou non, vous pouvez tirer profit du fait que nul est Falsey et faire ce

@posts=Post.all(:joins => :tags,:conditions=>(params[:tag_name] ? 
        { :tags => { :tag_name => params[:tag_name] }} : {} 

        ) 
       ) 

Mais c'est assez laid. Il pourrait être préférable de faire quelque chose comme cela pour le rendre plus clair ce que vous faites:

@posts = if params[:tag_name] 
      Post.all 
     else 
      Tag.find_by_name(params[:tag_name], :include => :posts).posts 
     end 
+0

Ok, liens groupe tag excellent travail, et aucune erreur à la terre sur/messages, mais deux choses: d'abord, il semble afficher chaque entrée de poste trois fois aa rang, et le second, il est seulement l'affichage des messages qui ont effectivement des balises (trois fois). Toutes les idées (nouveau à ruby ​​si vous ne pouvez pas dire). Merci pour l'aide. – bgadoci

+0

aussi, j'ai essayé le dernier, nettoyé des solutions, mais n'a pas reconnu les «pages». – bgadoci

+0

effectivement, juste regardé, l'affichage répété est directement corrélée au nombre d'étiquettes que le poste a. Trois balises = affichées trois fois, etc. – bgadoci

0

Le paramètre auquel vous essayez d'accéder est nul, et pas seulement vide. Une façon de résoudre ce problème est l'appel nul? au lieu de vide? dans votre code. Cela a fonctionné pour moi:

@posts=Post.all(:joins => :tags,:conditions=>(params[:tag_name].nil? ? {}: 
        { :tags => { :tag_name => params[:tag_name] }} 
        ) 
       )