前提・実現したいこと
自分の認識の確認がしたいです。
Railsチュートリアルの14章の、ユーザーをフォローするfollowメソッド内のコードの意味を自分なりに理解してみたのですが、いくつか疑問があり質問しました。
###確認したいこと
通常データをレコードに保存する場合はsave
メソッドやcreate
メソッドを使って処理すると思っていたのですが、チュートリアル内ではそのどちらのメソッドも使用せずにユーザーをフォローし、その関係を記録しています。
current_user.follow(other_user)
といった形で使うfollow
メソッドでは
following << other_user
という表記で処理を済ましています。
この演算子<<
については別のサイトで調べたところ
Active Record の関連付け (アソシエーション) 4.3 has_many関連付けの詳細
4.3.1 has_manyで追加されるメソッド
has_many関連付けを宣言したクラスでは、以下の17のメソッドを自動的に利用できるようになります。
collection
collection<<(object, ...) #これ?
以下略
という記載を見つけました。
collection<<(object, ...)
collection<<メソッドは、1つ以上のオブジェクトをコレクションに追加します。このとき、追加されるオブジェクトの外部キーは、呼び出し側モデルの主キーに設定されます。
この
このとき、追加されるオブジェクトの外部キーは、呼び出し側モデルの主キーに設定されます。
という記述がいまいち理解できません。
理解したいのは以下の2つです。
- 今回の場合主キーはどれになるのでしょうか。
- この
<<
でなぜ、active_relationshipsテーブルに対してユーザーをフォローした記録をsave
ないしはcreate
メソッドを使わずに記録できるのでしょうか。
よろしくお願いします。
###コード
ruby
1app/models/user.rb 2 3class User < ApplicationRecord 4 has_many :microposts, dependent: :destroy 5 has_many :active_relationships, class_name: "Relationship", 6 foreign_key: "follower_id", 7 dependent: :destroy 8 has_many :passive_relationships, class_name: "Relationship", 9 foreign_key: "followed_id", 10 dependent: :destroy 11 has_many :following, through: :active_relationships, source: :followed 12 has_many :followers, through: :passive_relationships, source: :follower 13 . 14 . 15 . 16end
ruby
1app/models/relationship.rb 2 3class Relationship < ApplicationRecord 4 belongs_to :follower, class_name: "User" 5 belongs_to :followed, class_name: "User" 6 validates :follower_id, presence: true 7 validates :followed_id, presence: true 8end
html
1#ユーザーをフォローする際のフォーム 2#app/views/users/_follow.html.erb 3 4 <%= form_for(current_user.active_relationships.build) do |f| %> 5 <div><%= hidden_field_tag :followed_id, @user.id %></div> 6 <%= f.submit "Follow", class: "btn btn-primary" %> 7<% end %>
ruby
1#app/controllers/relationships_controller.rb 2 3class RelationshipsController < ApplicationController 4 before_action :logged_in_user 5 6 def create 7 user = User.find(params[:followed_id]) 8 current_user.follow(user) 9 redirect_to user 10 end 11 12 def destroy 13 user = Relationship.find(params[:id]).followed 14 current_user.unfollow(user) 15 redirect_to user 16 end 17end
回答1件
あなたの回答
tips
プレビュー