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

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

ただいまの
回答率

91.33%

  • Ruby on Rails 4

    2158questions

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

他モデル間フォローでのajax実装方法とは?Part2

解決済

回答 2

投稿 2016/10/21 16:31 ・編集 2016/10/21 21:09

  • 評価
  • クリップ 0
  • VIEW 411

s.k

score 241

前提・実現したいこと

他モデル間でのいいね!機能にajaxを実装したい。
二度目のajaxの質問で大変恐縮です。

いいね!をするまでの流れとしては
Userログイン→Shopindexページ→Shopshowページ→Shopユーザーの投稿のいいね!リンクを押す
→ajax発動!

を予定しています。

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

いいね!機能のコントローラーである、goods_controller.rb中のcreateメソッド・destroyメソッドのredirect_to Shop.find(params[:id])が作動しません。

→いいね!リンクを押しても更新ボタンを押さない限り表示がいいね!を取り消すに切り替わりません。

【goods_controller.rb】

class GoodsController < ApplicationController
     before_action :logged_in_user

    def create
        @micropost = Micropost.find(params[:micropost_id])
        @good = current_user.goods.build(micropost_id: @micropost.id)
        @good.save
    end


    def destroy
        @good = current_user.goods.find_by!(micropost_id: params[:micropost_id])
        @good.destroy
    end
end

@goodデータはコンソールで確認しましたところ、
格納されています。

[2] pry(main)> Good.first
  Good Load (1.1ms)  SELECT  "goods".* FROM "goods"  ORDER BY "goods"."id" ASC LIMIT 1
=> #<Good:0x00000004fa17f8
 id: 20,
 user_id: 2,
 shop_id: nil,
 created_at: Fri, 21 Oct 2016 07:17:03 UTC +00:00,
 updated_at: Fri, 21
Oct 2016 07:17:03 UTC +00:00,
 micropost_id: 2>

 

※shop_idはまちがえて作ってしまいました。
ですので、私はcreateメソッドdestroyメソッドの引数に問題があるのではないかと思います。
※更新するといいね!→いいね!を取り消す、いいね!を取り消す→いいね!と表示が切り替わります。

【create.js.erb】

$('#follow_form').html('<%= escape_javascript(render("goods/good_links")) %>');

【destroy.js.erb】

$('#follow_form').html('<%= escape_javascript(render("microposts/micropost")) %>');

【micropost/_micropost.html.erb】

<li id="micropost-<%= micropost.id %>">
  <!-- User ver-->
  <% 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 %>
  <!-- Shop ver-->
  <% 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 %>

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

          <!-- お気に入り登録リンク user-to-shop -->←ここから本件該当部分です!
          <% if user_signed_in? %>
            <% if !current_user?(micropost.user) %>
              <div id="follow_form">
                <%= render 'goods/good_links', micropost: micropost %>
              </div>
            <% end %>
          <% end %>←ここまで本件該当部分です!

  <% end %>
</li>

一応、パーシャルも追記します!

【goods/_good_links.html.erb】

<% if micropost.gooded_by? current_user %>
     <%= link_to "お気に入りの解除", micropost_goods_path(micropost.id), method: :delete, remote: true %>
<% else %>
     <%= link_to "お気に入り登録", micropost_goods_path(micropost.id), method: :post, remote: true %>
<% end %>

pathの定義も書いておきます!

【routes.rb】

省略
 resources :microposts, only:[:create, :destroy] do
    resource :favorites, only: [:create, :destroy]
    resource :likes, only: [:create, :destroy]
    resource :goods, only: [:create, :destroy]
  end
省略

【micropost.rb】

省略
  def gooded_by? user
     goods.where(user_id: user.id).exists?
  end
省略

何個か違う引数を試したのですがだめでした。。。
ヘルプミーです。。。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • cameluby

    2016/10/21 19:36

    create、destroyメソッドのredirect_toの行を削除した上で、micropost.html.erbのコードを追記してください。何か分かると思います

    キャンセル

  • s.k

    2016/10/21 21:01

    camelubyさん お疲れ様です!かしこまりました!

    キャンセル

回答 2

checkベストアンサー

+1

うまくいっていないのは、partialにMicropostのオブジェクトが渡っていないからです。
なのでpartialからmicropostという変数を見ることができず、エラーになってしまいます。

以下のようにdestroyアクションでも@micropostを渡してあげるようにし、

class GoodsController < ApplicationController
     before_action :logged_in_user

    def create
        @micropost = Micropost.find(params[:micropost_id])
        @good = current_user.goods.build(micropost_id: @micropost.id)
        @good.save
    end


    def destroy
         @micropost = Micropost.find(params[:micropost_id])
        @good = current_user.goods.find_by!(micropost_id: @micropost.id)
        @good.destroy
    end
end

それぞれのviewで、それぞれのpartialにmicropostとして、@micropostを渡してあげましょう。

# create.js.erb
$('#follow_form').html('<%= escape_javascript(render("goods/good_links", micropost: @micropost)) %>');
# destroy.js.erb
$('#follow_form').html('<%= escape_javascript(render("microposts/micropost", micropost: @micropost)) %>');

投稿 2016/10/21 21:58

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/10/21 23:43

    できました…
    camelubyさん、ありがとうございます!
    他もパーシャルにオブジェクトを記載しないで機能していたのでわかりませんでした。
    それと、今の段階でdestroyに@micropostを置くこと自体わからなかったと思います。
    プログラマーさんのみなさんから比べれば、大したことない時間だと思いますが、2~3時間悩んで先に進まなかったので非常に助かりました!
    こんなに丁寧に解説していだたき感激です!
    精進します!!!!!

    キャンセル

0

他モデル間フォローでのajax実装方法とは? でも書きましたが

GoodsController#destroy で destroy.js.erb を render したいんですよね? (違ったらごめんなさい。)

であれば 

redirect_to Shop.find(params[:id])


を消さなければいけません。

1つのアクションではrenderredirect_toどちらかしかできないと思います。

投稿 2016/10/21 16:54

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/10/21 18:09


    hana-daさん
    ありがとうございます。

    jsでのrenderとGoodsController#destroyのredirect_toどちらかしかできないということは、redirect_toが機能している場合、ajaxは機能していないということですか??

    hana-daさんの指摘を受けまして、createとdestroyのredirect_toを削除しました!
    しかし、どうもうまくいきません。

    ターミナルを見るとエラー表示がありました。
    もしかしたら、僕は違うところで何かミスをしていたのでしょうか??

    下に書きましたのでみてほしいです!


    ActionView::Template::Error (undefined local variable or method `micropost' for #<#<Class:0x00000003eb7ac8>:0x007fad0448e050>
    Did you mean? micropost_url):
    1: <% if micropost.gooded_by? current_user %>
    2: <%= link_to "お気に入りの解除", micropost_goods_path(micropost.id), method: :delete, remote: true %>
    3: <% else %>
    4: <%= link_to "お気に入り登録", micropost_goods_path(micropost.id), method: :post, remote: true %>
    app/views/goods/_good_links.html.erb:1:in `_app_views_goods__good_links_html_erb___806277895404488579_70190537737660'
    app/views/goods/destroy.js.erb:1:in `_app_views_goods_destroy_js_erb__1094949354476025829_70190611118380'

    自分でも考えて見たのですがわかりませんでした。。。

    キャンセル

  • 2016/10/21 18:46

    teratailさんは一問一答を望んでおられるようです。
    コメントの中に質問を書かれてると、引用も ``` も効かず非常にみづらい上に回答も書きにくいですので追加の質問がある場合は別の質問にされる事をおすすめいたします。

    > redirect_toが機能している場合、ajaxは機能していないということですか??

    ajaxを誤解しているようです。
    ajaxは機能しておりコントローラに対する1回アクションではredirect_toかrenderどちらかしかできないという事です。



    初めのうちは1つ問題を解決するとまた別の問題が発生しゴールになかなか辿りつけないという事はよくあります。根気強く1つづつ解消していきましょう。それがあなたの血となり肉となります。

    ところで http://railstutorial.jp というサイトは御存じでしょうか?
    このチュートリアルを完了できると基本的な事は全て身につくすばらしいチュートリアルですので回り道を思わずに、まずは1度完了めざしてがんばってみられる事をおすすめいたします。

    キャンセル

  • 2016/10/21 19:00

    読みづらいですよね。。
    すいません。。。

    気を付けます。

    rails tutorialはやったのですが、どうもajaxの部分がわからず、もがしていました。。。

    キャンセル

  • 2016/10/22 07:22 編集

    昨晩は早めに寝ちゃったんですが cameluby さんが解決してくれたようでよかったです。

    rails tutorialやられたんですね。よかったです。
    であれば、今回の質問はajaxあんまり関係ないんでいけそうな気がするんですが。。。。

    まぁ解決してよかったです◎

    キャンセル

  • 2016/10/24 15:39


    hana-daさん

    やったんですが、すべてを理解はしきれなくて、、、
    実践でわからないところを補填していこうとしてます!泣

    毎度、ご返答いただきありがとうございます!

    キャンセル

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

ただいまの回答率

91.33%

関連した質問

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

  • Ruby on Rails 4

    2158questions

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