2017-10-03 9 views
1

こんにちは、私はこのエラーを抱えています。記事の表示ページに関連する記事を表示しようとしたときに、は未定義のメソッド `articles 'をnil:NilClassにします。ここで未定義のメソッド `articles 'for nil:記事の表示ページに関連記事を表示しようとしたときのNilClass

は私のアプリのコード

articles_controller

tag.rb

class Tag < ApplicationRecord 
    has_many :taggings 
    has_many :articles, through: :taggings 

    def to_s 
    name 
    end 

end 

tagging.rb

class Tagging < ApplicationRecord 
    belongs_to :tag 
    belongs_to :article 
end 

です

class ArticlesController < ApplicationController before_action :find_article, only: [:show, :edit, :update, :destroy] before_action :owned_article, only: [:edit, :update, :destroy] before_action :authenticate_user!, except: [:index, :show] def index @articles = Article.all.order("created_at desc") end def show end def new @article = current_user.articles.build end def create @article = current_user.articles.build(article_params) if @article.save redirect_to @article else render 'new' end end def edit end def update if @article.update(article_params) redirect_to @article, notice: "Your article was successfully updated!" else render 'edit' end end def destroy @article.destroy redirect_to articles_path end private def find_article @article = Article.find(params[:id]) end def article_params params.require(:article).permit(:title, :content, :image, :tag_list) end def owned_article unless current_user == @article.user flash[:alert] = "That article does not belong to you!" redirect_to root_path end end 

エンド

記事は

<div class="container"> 
<div class="row text-white text-center"> 
    <div class="col-md-10 col-lg-10 ml-sm-auto mr-sm-auto article-show-col"> 
     <br> 
     <h1><%= @article.title %></h1> 
     <p class="text-muted">Posted on: <%=  @article.created_at.strftime('%-b %-d, %Y') %></p> 

     <p> 
      Tags: 
      <% @article.tags.each do |tag| %> 
      <%= link_to tag.name, tag_path(tag) %> 
      <% end %> 
     </p> 


     <!-- <br> --> 
     <div class="article-show-image"> 
      <%= image_tag @article.image.url(:wide) %> 
     </div> 
     <!-- <br> --> 
     <p><%= @article.content.html_safe %></p> 

     <hr class="index-hr"> 

     <h5>Broadcast this article</h5> 

     <%= social_share_button_tag("Hey! Checkout this new article from TWM!") %> 

     <hr class="index-hr"> 

     **<h5>Related Articles</h5> 
     <% @tag.articles.each do |article| %> 
      <li><%= link_to article.title, article_path(article) %></li> 
     <% end %>** 

     <div class="btn-group"> 
      <%= link_to "Back", articles_path, class: "btn-custom btn-sm" %> 
      <% if user_signed_in? %> 
       <% if @article.user_id == current_user.id %> 
        <%= link_to "Delete", article_path(@article), method: :delete, data: { confirm: "Are you sure you want to delete this article?" }, class: "btn-custom btn-sm" %> 
        <%= link_to "Edit", edit_article_path, class: "btn-custom btn-sm" %> 
       <% end %> 
      <% end %> 
     </div> 
    </div> 
</div> 

タグコントローラ

class TagsController < ApplicationController 
before_action :find_article, only: [:show, :edit, :update, :destroy] 

def index 
    @tags = Tag.all.order("created_at desc") 
end 

def show 
end 

def destroy 
    @tag.destroy 
    redirect_to tags_path 
end 

private 

def find_article 
    @tag = Tag.find(params[:id]) 
end 
end 

ショーVIをshow.html.erbタグ

<div class="container text-white text-center"> 

<h1>Articles Tagged with <%= @tag.name %></h1> 

<ul> 
    <% @tag.articles.each do |article| %> 
    <li><%= link_to article.title, article_path(article) %></li> 
    <% end %> 
</ul> 

のためのEWはありがとうございました!

+0

'routes.rb'ファイルを投稿し、' show'メソッドが定義されている行を必ず含めてください。 'id'は' params'から引き出す必要のある属性の名前ではない可能性があります。 – anothermh

+0

あなたの記事show.html.erbに、あなたは*@tag.articlesを使用していて、* * @ tag *は存在しません。 –

答えて

0

ここでは、あなたの問題を解決するためのより長い回答があります。問題は、あなたが表示しているarticletagを共有するすべてのarticlesを取得したいと考えていますが、おそらく関連記事のリストに現在の記事を表示していない可能性があります。私はあなたのArticleモデルにrelated_articlesメソッドを追加し、あなたのビューでそれを呼び出すことによってこれを達成するでしょう。

app/models/article.rbに次のメソッドを追加します。

def related_articles 
    Article.joins(:tags).where(tags: { id: self.tags.pluck(:id) }).where.not(id: self.id) 
end 

上記のクエリは、自分自身を除外しながら、一致するタグを持つ記事のすべてを返す必要があります。

あなたは今のあなたのビューに関連する記事のセクションを置き換えることができます。

**<h5>Related Articles</h5> 
<% @article.related_articles.each do |article| %> 
    <li><%= link_to article.title, article_path(article) %></li> 
<% end %>** 

厳密にあなたの問題に関連しますが、言及する価値はない最後の注意。 @article.tagsを反復すると、ビューでN + 1のクエリが作成されます。これらは非常に非効率的です。良いニュースは、次のようにあなたのarticles_controllerfind_articles方法を変え、これは単純でeager loadingで固定することができるということである。

def find_article 
    @article = Article.includes(:tags).find(params[:id]) 
end 

related_articlesクエリを記述するためのより効率的な方法があるかもしれませんが、これは動作するはずです。

EDIT:related_articlesクエリは、次の書き込みの

もう一つの方法。これにより同じ結果が得られます。より多くの処理をデータベースに移し、結果としてデータベースへの呼び出しが少なくなります。

def related_articles 
    Article.distinct.joins(tags: :articles).where.not(id: self.id) 
end 
+0

私はあなたが私が望んでいたものを達成することができたと言ったようにrelated_articlesメソッドを定義した後...あなたは私のストレスの人を救った、感謝しています。しかし、私がfind_articleメソッドを変更したとき、私はこのエラーを持っていました "未定義のメソッド' for 'for Article:0x50478f0> " – Lashe

+0

良い点。 'インクルード'は 'find'の前になければなりません。私は答えを更新します。 –

+0

私は 'related_articles'のためのより効率的なクエリを使用する答えを更新しました –

0

あなたのArticlesControllerは、表示ビューで使用されている間、@タグ変数をインスタンス化していません。あなたのshow.html.erb

0

、あなたがやろうとしている:

<div class="container"> 
    <div class="row text-white text-center"> 
    <div class="col-md-10 col-lg-10 ml-sm-auto mr-sm-auto article-show-col"> 

     ... 

     <% @tag.articles.each do |article| %> 
      <li><%= link_to article.title, article_path(article) %></li> 
     <% end %>** 

     ... 

    </div> 
    </div> 
</div> 

しかし、ちょっと、それをチェックアウト!あなたのshowアクションで何@tagは:

class ArticlesController < ApplicationController 
    before_action :find_article, only: [:show, :edit, :update, :destroy] 
    before_action :owned_article, only: [:edit, :update, :destroy] 
    before_action :authenticate_user!, except: [:index, :show] 

    ... 

    def show 
    #look! no @tag 
    end 

    ... 

end 
0

@tag変数は、あなたのArticlesControllerに設定されていないされていないので、articles show.html.erbに利用できません。

この回答には問題が説明されていますが、解決策はありません。解決策を使って新しい回答を投稿しました。

関連する問題