質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.33%

  • Ruby on Rails 4

    2158questions

    Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

他モデルshowページへ飛ぶ際の条件分岐は??

解決済

回答 2

投稿 2016/10/19 16:00 ・編集 2016/10/20 11:25

  • 評価
  • クリップ 1
  • VIEW 515

s.k

score 241

前提・実現したいこと

他モデルへのshowページへ飛べるように条件分岐をしたいです。

例えば、あるユーザーがUserとしてログインしていたとします。
そこから、Shopユーザーのshowページへ飛べるというイメージです。

Userログイン→Shopindexページ→Shopshowページ

発生している問題・エラーメッセージ

shopindexページから
shopindexページ

株式会社ソラコムというshowページリンクをクリックすると、

undefined method `email' for nil:NilClass

showページのコードです。
下から6行目の_micropostパーシャルに問題があります。

【shops/show.html.erb】

<% provide(:title, @shop.shopname) %>
<div class="row">
  <!-- ページ左 -->
  <aside class="col-md-4">
    <section class="shop_info">
      <h1>
        <!-- アイコン -->
        <%= gravatar_to @shop %>
        <!-- ユーザー名 -->
        <%= @shop.shopname %>
      </h1>
    </section>
    <section class="stats">
      <!-- follow,followerリンク -->
      <%= render 'shared/stats'%>
    </section>
  </aside>


     <!-- ページ右 -->
     <div class="col-md-8">
        <!-- follow(shop-to-shop)ボタン -->
        <%= render 'friend_form' if shop_signed_in? %>

        <!-- follow(user-to-shop)ボタン -->
        <% if user_signed_in? %>
            <div id="follow_form">
              <%= render 'associates/associate_links'%>
            </div>
        <% end %>

        <% if @shop.microposts.any? %>
          <!-- 投稿数 -->
          <h3>Microposts (<%= @shop.microposts.count %>)</h3>
          <ol class="microposts">
            <!-- 投稿一覧 -->
            <%= render @microposts %>
          </ol>
          <%= will_paginate @microposts %>
        <% end %>
     </div>
</div>


_micropostパーシャルです。
4行目のgaravatar_forがエラーとなっています。

【_micropost.html.erb】

<li id="micropost-<%= micropost.id %>">
  <% if user_signed_in? %>
       <!-- ユーザーアイコン -->
       <%= link_to gravatar_for(micropost.user, size: 50), micropost.user %>
      <!-- ユーザー名 -->
      <span class="user"><%= link_to micropost.user.username, micropost.user %></span>
      <span class="content">
        <!-- 投稿文 -->
        <%= micropost.content %>
        <!-- 投稿写真 -->
        <%= image_tag micropost.picture.url if micropost.picture? %>
      </span>
      <!-- 投稿時間 -->
      <span class="timestamp">
        Posted <%= time_ago_in_words(micropost.created_at) %> ago.
      </span>

          <!-- 削除リンク -->
          <% if current_user?(micropost.user) %>
              <%= link_to "delete", micropost, method: :delete, data: { confirm: "You sure?" } %>
          <% end %>

          <!-- お気に入り登録リンク -->
          <% if !current_user?(micropost.user) %>
            <div id="follow_form">
              <%= render 'favorites/favorite_links', micropost: micropost %>
            </div>
          <% end %>
  <% elsif shop_signed_in? %>
       <!-- ショップアイコン -->
      <%= link_to gravatar_to(micropost.shop, size: 50), micropost.shop %>
      <!-- ショップ名 -->
      <span class="shop"><%= link_to micropost.shop.shopname, micropost.shop %></span>
      <span class="content">
        <!-- 投稿文 -->
        <%= micropost.content %>
        <!-- 投稿写真 -->
        <%= image_tag micropost.picture.url if micropost.picture? %>
      </span>
      <!-- 投稿時間 -->
      <span class="timestamp">
        Posted <%= time_ago_in_words(micropost.created_at) %> ago.
      </span>

          <!-- 削除リンク -->
          <% if current_shop?(micropost.shop) %>
              <%= link_to "delete", micropost, method: :delete, data: { confirm: "You sure?" } %>
          <% end %>

          <!-- いいね!リンク -->
          <% if !current_shop?(micropost.shop) %>
            <div id="follow_form">
              <%= render 'likes/like_links', micropost: micropost %>
            </div>
          <% end %>
  <% end %>
</li>

gravatarメソッドです。
コードは以下です。
この4行目、emailがnilだとエラーメッセージがでます。。。

【users_helper】

module UsersHelper
    def gravatar_for(user, options = { size: 50 } )
      size = options[:size]
      gravatar_id = Digest::MD5::hexdigest(user.email.downcase) 
      gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
      image_tag(gravatar_url, alt: user.username, class: "gravatar")
    end

    def current_user?(user)
      user == current_user
    end
end

_micropostパーシャルの時にshop専用に用意したメソッドgravatar_toメソッドを使えばこのような問題は起こらないと思うのです。

しかし、_micropostパーシャルの条件分岐がuser_signed_in?しかないので、garavatar_forを使わざるを得ない状況に陥ってしまいます。

そこで、この問題を解決できる条件分岐はないかお聞きしたいです!

よろしくおねがいします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • cameluby

    2016/10/19 23:47 編集

    もう少し分かりやすく質問していただけると助かります。 やりたいことが分かれば、答えることができると思うので!

    キャンセル

  • s.k

    2016/10/20 11:26

    すいません!もう一度書いてみました!どうしても伝えたいことがありすぎてまとまりませんが頑張りました!まだまだ、シンプルに書けますので、情報修正の依頼をガンガンだしてください!camelubyさんよろしくお願いします!

    キャンセル

回答 2

checkベストアンサー

0

<%= link_to gravatar_for(micropost.user, size: 50), micropost.user %>


ここで呼ばれている、micropost.usernilになっているようです。
micropostに紐付いたuserが存在しないことが原因だと思います。

shop専用に用意したメソッドgravatar_toメソッドを使えばこのような問題は起こらないと思うのです。

これがどういう意味か分かりませんでした。


_micropost.html.erbをusers_controllerとshops_controllerで共通で使用したいということであれば、
controller_nameメソッドを使用して分岐することができます。
質問者さんが追加した回答をみると、users_controllerの時は上の分岐、shops_controllerの時は下の分岐になっていますね。
なのでそれぞれ、

  <% if controller_name = "users" %> ←追加


<% elsif controller_name = "shops" %> ←追加


のようにしたら良さそうです。
controllerからは@page@accountの記述は消して構いません。

ただ、これだと共有できている部分が

<li id="micropost-<%= micropost.id %>">
</li>


しか無いので、ファイル自体を分けても良いのかな?と思いますが。。。

# _micropost.html.erb

<li id="micropost-<%= micropost.id %>">
  <% if controller_name = "users" %> ←追加
       <!-- ユーザーアイコン -->
       <%= link_to gravatar_for(micropost.user, size: 50), micropost.user %>
      <!-- ユーザー名 -->
      <span class="user"><%= link_to micropost.user.username, micropost.user %></span>
      <span class="content">
        <!-- 投稿文 -->
        <%= micropost.content %>
        <!-- 投稿写真 -->
        <%= image_tag micropost.picture.url if micropost.picture? %>
      </span>
      <!-- 投稿時間 -->
      <span class="timestamp">
        Posted <%= time_ago_in_words(micropost.created_at) %> ago.
      </span>

          <!-- 削除リンク -->
          <% if current_user?(micropost.user) %>
              <%= link_to "delete", micropost, method: :delete, data: { confirm: "You sure?" } %>
          <% end %>

          <!-- お気に入り登録リンク user-to-user-->
          <% if user_signed_in? %>
            <% if !current_user?(micropost.user) %>
              <div id="follow_form">
                <%= render 'favorites/favorite_links', micropost: micropost %>
              </div>
            <% end %>
          <% end %>

  <% elsif controller_name = "shops" %> ←追加
       <!-- ショップアイコン -->
      <%= link_to gravatar_to(micropost.shop, size: 50), micropost.shop %>
      <!-- ショップ名 -->
      <span class="shop"><%= link_to micropost.shop.shopname, micropost.shop %></span>
      <span class="content">
        <!-- 投稿文 -->
        <%= micropost.content %>
        <!-- 投稿写真 -->
        <%= image_tag micropost.picture.url if micropost.picture? %>
      </span>
      <!-- 投稿時間 -->
      <span class="timestamp">
        Posted <%= time_ago_in_words(micropost.created_at) %> ago.
      </span>

          <!-- 削除リンク -->
          <% if current_shop?(micropost.shop) %>
              <%= link_to "delete", micropost, method: :delete, data: { confirm: "You sure?" } %>
          <% end %>

          <!-- いいね!リンク shopver-to-shop -->
            <% if shop_signed_in? %>
              <% if !current_shop?(micropost.shop) %>
                <div id="follow_form">
                  <%= render 'likes/like_links', micropost: micropost %>
                </div>
              <% end %>
            <% end %>

  <% end %>
</li>

投稿 2016/10/20 21:16

編集 2016/10/22 00:13

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/20 21:50

    上をみてほしいです!!

    キャンセル

  • 2016/10/20 21:50

    補足してみました。

    キャンセル

  • 2016/10/20 22:06

    _micropost.html.erb
    をusers_controllerとshops_controllerで共通で使用しているということでしょうか?

    キャンセル

  • 2016/10/21 16:09

    はい!

    キャンセル

  • 2016/10/22 00:13

    それを踏まえ追記しました。

    キャンセル

  • 2016/10/22 00:22

    camelubyさん
    ありがとうございます!

    そんな便利なメソッドがあるのですか…
    確かにファイルを分けた方がいいですよね。
    これからどんどん機能を書いていけば、分岐も複雑になっていきますし!

    完成はいつになるか…
    回答がわかりやすすぎて、逆に申し訳なく感じてきました。。。

    明日、ファイル分けてみます!

    キャンセル

  • 2016/10/22 00:29

    方法はいくらでもありますし、最初は「とりあえず書いてみる、動くものを書いてみる」というのも重要だと思うので、質問者さんの@accountと@pageの方法も決して駄目なわけではありませんよ!
    ただRailsが用意してくれているメソッドを使うと簡単に書けることも多いので、段々と知っていけば良いと思います!
    いろいろ試してみてください!

    キャンセル

  • 2016/10/22 10:08

    はい!

    キャンセル

-1

自分で荒いですが、条件分岐を作ってみました。

【users_controller.rb】

・・・・省略・・・・
  def show
    @account = 3←追加
    @page = 2←追加
    @user = User.find(params[:id])
    @microposts = @user.microposts.paginate(page: params[:page])
  end
・・・・省略・・・・

【shops_controller.rb】

def show
    @account = 4 ←追加
    @page = 1 ←追加
    @shop = Shop.find(params[:id])
    @microposts = @shop.microposts.paginate(page: params[:page])
  end
<li id="micropost-<%= micropost.id %>">
  <% if @page == 2 || @account == 3 %> ←追加
       <!-- ユーザーアイコン -->
       <%= link_to gravatar_for(micropost.user, size: 50), micropost.user %>
      <!-- ユーザー名 -->
      <span class="user"><%= link_to micropost.user.username, micropost.user %></span>
      <span class="content">
        <!-- 投稿文 -->
        <%= micropost.content %>
        <!-- 投稿写真 -->
        <%= image_tag micropost.picture.url if micropost.picture? %>
      </span>
      <!-- 投稿時間 -->
      <span class="timestamp">
        Posted <%= time_ago_in_words(micropost.created_at) %> ago.
      </span>

          <!-- 削除リンク -->
          <% if current_user?(micropost.user) %>
              <%= link_to "delete", micropost, method: :delete, data: { confirm: "You sure?" } %>
          <% end %>

          <!-- お気に入り登録リンク user-to-user-->
          <% if user_signed_in? %>
            <% if !current_user?(micropost.user) %>
              <div id="follow_form">
                <%= render 'favorites/favorite_links', micropost: micropost %>
              </div>
            <% end %>
          <% end %>

  <% elsif @page == 1 || @account == 4 %> ←追加
       <!-- ショップアイコン -->
      <%= link_to gravatar_to(micropost.shop, size: 50), micropost.shop %>
      <!-- ショップ名 -->
      <span class="shop"><%= link_to micropost.shop.shopname, micropost.shop %></span>
      <span class="content">
        <!-- 投稿文 -->
        <%= micropost.content %>
        <!-- 投稿写真 -->
        <%= image_tag micropost.picture.url if micropost.picture? %>
      </span>
      <!-- 投稿時間 -->
      <span class="timestamp">
        Posted <%= time_ago_in_words(micropost.created_at) %> ago.
      </span>

          <!-- 削除リンク -->
          <% if current_shop?(micropost.shop) %>
              <%= link_to "delete", micropost, method: :delete, data: { confirm: "You sure?" } %>
          <% end %>

          <!-- いいね!リンク shopver-to-shop -->
            <% if shop_signed_in? %>
              <% if !current_shop?(micropost.shop) %>
                <div id="follow_form">
                  <%= render 'likes/like_links', micropost: micropost %>
                </div>
              <% end %>
            <% end %>

  <% end %>
</li>

上記を追加したことで、
①Userログイン状態で、Shopモデルからデータを取りだす(shops/show.html.erbを表示させる)
②Userログイン状態で、Userモデルからデータを取り出す(users/show.html.erbを表示させる)
③Shopログイン状態で、Userモデルからデータを取りだす(users/show.html.erbを表示させる)
④Shopログイン状態で、Shopモデルからデータを取り出す(shops/show.html.erbを表示させる)

ように無理やりしました。

>camelubyさん

画像表示のgaravatar_forを最初にusers.helper.rbで定義しましたが、
そのメソッドはShopモデルでは使えませんでした。(メソッド内容がuserのデータを取り出すことしかできないため)ですので、Shops.helper.rbで名前を少し変えて定義しました。
それが↓にあるものです。

【users.helper.rb】

def gravatar_for(user, options = { size: 50 } )
      size = options[:size]
      gravatar_id = Digest::MD5::hexdigest(user.email.downcase) 
      gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
      image_tag(gravatar_url, alt: user.username, class: "gravatar")
    end

【shops.helper.rb】

def gravatar_to(shop, options = { size: 50 } )
      size = options[:size]
      gravatar_id = Digest::MD5::hexdigest(shop.email.downcase)
      gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
      image_tag(gravatar_url, alt: shop.shopname, class: "gravatar")
  end

投稿 2016/10/20 21:49

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.33%

関連した質問

同じタグがついた質問を見る

  • Ruby on Rails 4

    2158questions

    Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。