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
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を追加。