4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

enumで下書き、公開機能を実装

Posted at

いろいろやったので備忘録

概要 要件

  • 美容室のページに下書き機能を実装する
  • デフォルト下書き、編集→保存、及び、ボタンでステータスを変更できるようにする
  • その美容室に紐づくモデル(スタイリスト、スタイル、メニュー)も非公開にする
  • ログインしていれば下書き状態のものも見ることができる
  • ログインしていても他のユーザーの非公開ページは見れない

Bootstrap4、Rails6

完成(目標物)

スクリーンショット 2020-03-21 10.43.48.png スクリーンショット 2020-03-21 10.44.42.png

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 %>
スクリーンショット 2020-03-21 10.44.42.png

ステータス表示

 <% 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 %>
スクリーンショット 2020-03-21 11.19.58.png

終わりに

書き方等、変なところあれば、ご指摘ください。
以下、記事参考にさせていただきました。

参考記事

『Rails』enumを使って下書き記事と公開記事を保存できるようにした
link_to でenumのステータスを変更する方法
Rails enumについてまとめておく

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?