rails 独学して軽くにちゃんまとめつくる

読者です 読者をやめる 読者になる 読者になる

rails独学して軽く2ちゃんまとめビルダーをつくる。

rails tutorial読破→2chまとめビルダー作成→アメリカでインターンシップ→恋活SNSを作成・・・・・→音で感触をつくり感触をあつめたライブラリをつくる

RailsTutorial のアクセス制御の correct_user の説明

rails tutorial でやった correct_user について説明する。

13章でやったようにマイクロポストを削除するときは current_user とマイクロポストの作者を比較して正しい場合のみ削除を実行するというものであった。結局やることはこれだけで、日本語にしたらわかるのだが、rails tutorial で書かれているコードはちょっとややこしいので改めて考えてみる。

リスト 13.52 をみてみると

  before_action :correct_user,   only: :destroy
・
・
・

    def correct_user
      @micropost = current_user.microposts.find_by(id: params[:id])
      redirect_to root_url if @micropost.nil?
    end

こんな風に書いてある。肝の部分は current_user.microposts.find_by(id: params[:id]) この箇所なのだがこれをどう理解したらいいだろう。

話を簡単にしてみよう。以下の話は rails tutorial のコードとは異なるので話を理解するだけでいい。結局比較したいことは自分(current_user) と micropost の著者が同じであることである。こんな風にユーザーとユーザーの比較したい。

f:id:mooooooooooriiiiii:20170414123352j:plain

だがアクセスしているリソースがマイクロポストであるため、マイクロポストからどうにかユーザーの情報を抽出したい。そうするためには user = Micropost.find(params[:id]).user_id とする。そしてこの user と current_user を比較することが、現在のユーザーとマイクロポストの著者を比較していることになる。だから correct_user を簡単に書き直すと請うなる。

def correct_user
  user = Micropost.find(params[:id].user_id)
  redirect_to root_url if current_user == user
end

f:id:mooooooooooriiiiii:20170414123540j:plain

だが tutorial では「current_userとマイクロポストのユーザー」というユーザー同士の比較ではなく、「current_userのマイクロポストとマイクロポスト」というマイクロポストの比較をしている。 図にすればこうなる。

f:id:mooooooooooriiiiii:20170414124456j:plain

current_user は複数のマイクロポストを持っている。その持っているものの中にいま削除しようとしているマイクロポストが含まれているか探している。まさにこのコードの日本語訳である @micropost = current_user.microposts.find_by(id: params[:id]) current__user.microposts で current_user の持っているすべてのマイクロポストを呼び出していて、 find_by(id: params[:id]) で削除しているマイクロポストが入っているかいなかを調べている。 その後もしなければ = (@micropost が nil) = current_user がそのマイクロポストを持っていなかったら root_path へ帰るようにしている。

ユーザーの比較でもマイクロポストの比較でも結局 current_user(図の左) と あるマイクロポスト(図の右)との比較であることに変わりはない。比較しているものは違っても結局していることは同じである。