いろいろやったので備忘録
概要 要件
- 美容室のページに下書き機能を実装する
- デフォルト下書き、編集→保存、及び、ボタンでステータスを変更できるようにする
- その美容室に紐づくモデル(スタイリスト、スタイル、メニュー)も非公開にする
- ログインしていれば下書き状態のものも見ることができる
- ログインしていても他のユーザーの非公開ページは見れない
Bootstrap4、Rails6
完成(目標物)
1、model
modelにstatusカラムを追加
rails generate migration AddStatusToSalon status:integer
追記
db/migrate/xxxxxxxx_add_status_to_salon.rb
def change
add_column :salons, :status, :integer, default: 0, null:false
end
defaultで0を指定
null: falseで、指定したカラムに空保存を防ぐ
rails db:migrate
enum定義
下書き:0
公開:1
salon.rb
enum status: { draft: 0, published: 1, deleted: 2 }
validates :status, inclusion: { in: Salon.statuses.keys }
2、View
salons/edit.html.erb
<div class="form-group">
<label>ステータス</label><br>
<%= form.select :status, [["下書き", "draft"],["公開", "published"]], id: "status", class: "form-control" %>
</div>
3、controller
元のソース
salons_controller.rb
def show
@hairstyles = @salon.hairstyles.order(id: "desc")
@hairstyles = @salon.hairstyles.rank(:row_order)
render layout: false
end
下書き状態の時でログインしていれば見れる。
公開だったら見れる
salons_controller.rb
def show
if (@salon.published? || user_signed_in? && @salon.draft?)
@hairstyles = @salon.hairstyles.order(id: "desc")
@hairstyles = @salon.hairstyles.rank(:row_order)
render layout: false
else
flash[:alert] = "非公開です ログインしてください"
redirect_to root_path
end
end
ログインしていても他のアカウントのページは見れない(自分のページしか見れない)
salons_controller.rb
def show
if (@salon.draft? && @salon.user.id != current_user.id)
flash[:alert] = "権限がありません"
redirect_to root_path
elsif (@salon.published? || user_signed_in? && @salon.draft?)
@hairstyles = @salon.hairstyles.order(id: "desc")
@hairstyles = @salon.hairstyles.rank(:row_order)
render layout: false
else
flash[:alert] = "非公開です ログインしてください"
redirect_to root_path
end
end
しかしこのままだと、紐づくモデルまでは効かないので、各コントローラーの見せたくないアクションにも追記
if (@salon.draft? && @salon.user.id != current_user.id)
flash[:alert] = "権限がありません"
redirect_to root_path
elsif (@salon.published? || user_signed_in? && @salon.draft?)
xxxxxxxxx
xxxxxxxxx
end
4、ボタンでステータスを変更できるようにする
modeにメソッドを作成
draftだったらpublishedに変更
publishedだったらdraftに変更
salon.rb
def toggle_status!
draft? ? published! : draft!
end
controller
salons_controller.rb
def toggle_status
@salon.toggle_status!
redirect_to dashboard_path, notice: 'ステータスを変更しました'
end
routes
routes.rb
resources :salons do
patch :toggle_status
end
view
店舗一覧ページ
dashborad.html.erb
<% if (salon.published?) %>
<%= link_to "非公開にする", salon_toggle_status_path(salon), method: :patch, class: "btn btn-outline-danger" %>
<% else %>
<%= link_to "公開する", salon_toggle_status_path(salon), method: :patch, class: "btn btn-outline-danger" %>
<% end %>
ステータス表示
<% if (salon.published?) %>
<div class="btn btn-primary mr-5 float-left">公開中</div>
<% else %>
<div class="btn btn-success mr-5 float-left">下書き</div>
<% end %>
終わりに
書き方等、変なところあれば、ご指摘ください。
以下、記事参考にさせていただきました。
参考記事
『Rails』enumを使って下書き記事と公開記事を保存できるようにした
link_to でenumのステータスを変更する方法
Rails enumについてまとめておく