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

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

新規登録して質問してみよう
ただいま回答率
87.20%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

解決済

ruby on rails チュートリアル 14章 フォロー機能のdestroyアクションの記述でわからないところがあります。

natecosan
natecosan

総合スコア23

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

1回答

0評価

1クリップ

1457閲覧

投稿2019/04/16 12:15

わからないこと

Ruby on Rails チュートリアル14章「14.2.4 [Follow] ボタン (基本編)」
のdestroyアクション実装の部分でわからないところがあるので質問させてください。

user = Relationship.find(params[:id).followed
ということは、
「Relatihonshipテーブルにおいて、idカラムがparams[:id]のフォロー中ユーザー」をuserとしているということですよね。
この場合、unfollowボタンのビュー記述部分に記載している「followed_id:@user.id」が上記のparams[:id]に当てはまるという理解で合っていますでしょうか?
そして、合っていたとしたら、find(params[:follwed_id]).followedと書かないのはなぜでしょうか?

雑多な説明で恐縮ですが、よろしくおねがいします・・・!

該当のソースコード

リスト 14.33: Relationshipsコントローラ
app/controllers/relationships_controller.rb

class RelationshipsController < ApplicationController before_action :logged_in_user def create user = User.find(params[:followed_id]) current_user.follow(user) redirect_to user end def destroy user = Relationship.find(params[:id]).followed #ここの部分 current_user.unfollow(user) redirect_to user end end

unfollowボタンのビュー記述部分

<%= form_for(current_user.active_relationships.find_by(followed_id: @user.id), html:{ method: :delete}) do |f| %> <%= f.submit "Unfollow", class: "btn" %> <% end %>

user.rb

def unfollow(other_user) active_relationships.find_by(followed_id: other_user.id).destroy end

良い質問の評価を上げる

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

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

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

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

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

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

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

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

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

回答1件

1

ベストアンサー

user = Relationship.find(params[:id).followed

ということは、
「Relatihonshipテーブルにおいて、idカラムがparams[:id]のフォロー中ユーザー」をuserとしているということですよね。

「Relatsionshipテーブルにおいて、idカラムがparams[:id]の行のフォロー中ユーザー」
という意味ならばそうです。

この場合、unfollowボタンのビュー記述部分に記載している「followed_id:@user.id」が上記のparams[:id]に当てはまるという理解で合っていますでしょうか?

いいえ、別です。
図 14.7にidカラムがないのが誤解の原因なのかな?と思いますが
Relatihonshipテーブルにもidカラムがあり、Userテーブルとは無関係にユニークな番号が振られているわけです。

図 14.7をこう読み替えるといいかもしれません。

follower_ididfollowed
112
127
331
742
1510
261
178
981

ただし、user

erb

<%= form_for(current_user.active_relationships.find_by(followed_id: @user.id), html:{ method: :delete}) do |f| %> <%= f.hidden_field :followed_id, @user.id %> <%= f.submit "Unfollow", class: "btn" %> <% end %>

とすることで

ruby

def destroy user = User.find(params[:followed_id]) # 省略 end

が可能です。

こうしなかった理由はCRUDとしての統一感を重視したのかなと思います。

Relationshipコントローラーのdestroyメソッドなんだから
Relationshipのidを渡して削除しようという考えかなと思います。

まぁ、つまり

ruby

class RelationshipsController def destroy Relationship.find(params[:id]).destroy end end

こうですね。

しかしこれでは、他人のフォロワーを勝手に解除できてしまいます。
そこで遠回りして、other_userを取得しcurrent_userを介して解除しています。

投稿2019/04/16 23:51

asm

総合スコア15127

良いと思った回答には高評価をしましょう。
評価が高い回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

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

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

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

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

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

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

コメント

natecosan

2019/04/17 12:05

回答ありがとうございます。 アプリケーション側でのコード実行順序がよく分かっておらず、混乱していたみたいです。。。 つまり、form_forタグのcurrent_user.active_relationships.find_by(followed_id: @user.id)の部分で先にfollowed_id: @user.idであるユーザーを探しておいて、そのレコードにあるidカラムの値をparams[:id]として受け取る→Relationshipの該当レコードを削除 ということですか?
asm

2019/04/17 13:16 編集

> form_forタグのcurrent_user.active_relationships.find_by(followed_id: @user.id)の部分で先にfollowed_id: @user.idであるユーザーを探しておいて current_user.active_relationships.find_by(followed_id: @user.id)は follower_id: current_user.idかつfollowed_id: @user.idなRelationshipを探しており そのidをparams[:id]としてコントローラに渡しています。 そして、コントローラ側はそのparams[:id]からRelationshipを探して(最終的に)削除しています
natecosan

2019/04/17 23:58

なるほど!わかりました。ありがとうございます!!

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

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

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

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。