チワワかわいいブログ

RUNTEQでrails勉強する日々の記録

2020/12/16 railsチュートリアル10章後半

一覧ページ作成

users_path => GET /users => indexアクションに到達
indexアクションは一番上、慣習的に順番が決まってる

複数のユーザーを生成するタスクを実装

faker gemを使ってそれっぽいデータを作れる

gem 'faker',                   '2.1.2'

db/seeds.rb 上で生成するコードを書く(コンソールでかける内容は書ける感じ)

# メインのサンプルユーザーを1人作成する
User.create!(name:  "Example User",
             email: "example@railstutorial.org",
             password:              "foobar",
             password_confirmation: "foobar")

# 追加のユーザーをまとめて生成する
99.times do |n|
  name  = Faker::Name.name
  email = "example-#{n+1}@railstutorial.org"
  password = "password"
  User.create!(name:  name,
               email: email,
               password:              password,
               password_confirmation: password)
end

rails db:seed でDBの更新を実行
ちなみに、もう一回rails db:seedを実行しても今回はすでにDBにあるメールアドレスがもう一回となるのでエラーになる
User.create! 「!」があると、nilではなくerrorを返す

pagenation

一覧表示をわかりやすく(1ページ30人とか)にするためwill_paginate gem を追加。

<%= will_paginate %>

viewのバーを表示したい部分にコードを追加。
gemを入れたことで、

User.pagenate(page: 1)

というメソッドが使えるようになっている。
これを使ってindexアクションを編集。

def index
  @users = User.paginate(page: params[:page])  #paramsに今のページが含まれる
end

f:id:ecolotta:20201216182805p:plain

URLにオプションが渡せる
http://localhost:3000/users?page=3

リファクタリング
<% @users.each do |user| %>
    <li>
      <%= gravatar_for user, size: 50 %>
      <%= link_to user.name, user %>
    </li>
  <% end %>

これを

<% @users.each do |user| %>
  <%= render user %>
<% end %>

でパーシャルを作成
さらに

<ul class="users">
  <%= render @users %>
</ul>

renderの引数に変数(@users = User.paginate(page: params[:page]))を渡すと、
@users.eachと同じ挙動・・・
renderにモデルのインスタンスの集合を渡したらパーシャルの中身を表示してくれる、という仕組みがある

ユーザーを削除する

管理権限あればユーザーの削除ができるようにする

rails generate migration add_admin_to_users admin:boolean

でカラムを追加
boolean型のデータは、true/falseであって欲しいが、データがない場合はnilになる
if文を書くときとかに3択になると手間なので、default値を設定する方がいい
boolean型のカラムでは以下のようなメソッドが使える

>> user.admin?  #booleanの中身は?
=> false
>> user.toggle!(:admin)  #中身をひっくり返す
=> true
>> user.admin?
=> true
destroy

管理者のみ削除できるように

<% if current_user.admin? && !current_user?(user) %> # current_userのadminがtrueで、渡されたユーザーがカレントユーザーで"なければ"trueを返す
    <%= link_to "delete", user, method: :delete,
                                  data: { confirm: "You sure?" } %> # method: :deleteを渡すことでdeleteリクエストになる 
<% end %>

削除リンクが見えているユーザーのみ削除できる状態だが、コマンドラインでDELETEリクエストを直接発行するという方法でサイトの全ユーザーを削除してしまうことができる可能性があるため、destroyアクションにもアクセス制御を行う必要があるとのこと。
before_actionを追加。