TOP BLOG Rails| enum|

『Rails』enumを使って下書き記事と公開記事を保存できるようにした

2019/09/03◉ 5 views



enumを使って下書き記事と公開記事を分けてみる


今回はaction textを使ったブログで、下書き記事を保存できるようにしました。

初学者なちょめこにはさっぱりわからなかった為、色々ググること数十分...

enumと出合いました!!!!

すごく簡単に実装できたので紹介します。

まずは参考記事

こちら

実装コード説明



まずはBlogモデルにstatusカラムを追加しinteger型にします。

他にboolean型もありますが今回はinteger型にしていきます。

追加するにはこうですね。

bin/rails g migration クラス名 カラム名:データ型( カラム名:データ型)

なので今回は

bin/rails g migration AddStatusToBlogs status:integer

ファイルが作成されるので少し付け加えます

db/migrate/00000000_add_status_to_blogs.rbに追加
class AddStatusToBlogs < ActiveRecord::Migration[6.0]
  def change
    add_column :blogs, :status, :integer, default: 0, null: false     ここを追加
  end
end

defaultで0を指定しときます。

null: falseで、指定したカラムに空の状態で保存させるのを防ぎます。

そしたらお決まりの〜〜〜

bin/rails db:migrate

これで追加されたと思います。

db/schema.rb



model


モデルにenumを設定していきます。

enum、属性名、属性の値(ハッシュ)で指定することでenumを定義することができる。

enum status: { draft: 0, published: 1 } ここを追加

has_one_attached :image
has_rich_text :body

statusカラムのdraft(下書き)を0に指定し

statusカラムのpublished(公開)を1に指定します。

キーと数字のハッシュを渡すと、数字がDBカラムに設定されます。

mysqlの中身を確認してみる


まずはログインします。

コマンドプロンプトを起動
bin/rails c
ログイン
mysql -u ユーザー名 -p
データーベース一覧
mysql> SHOW DATABASES;
ここでデーターベース名を選択します。ちなみに今回はpgmg_development
mysql> use pgmg_development;
テーブル一覧
mysql> show tables;
blogsテーブルの中身を見てみます。
mysql> select * from blogs order by status;

少し見にくいですが、statusカラムが数字で登録されていると思います。

enumの定義で、キーと数字のハッシュを渡すと、数字がDBカラムに設定されるのがわかるかと思います。
status



mysql> quit
これで終了

controllerの設定


次はcontrollerで公開記事と下書き記事を分けて表示させてみます。

記事一覧ページがあるとします。

このブログサイトだとBlogページですね

blogページ

このページではenumがpublished(公開)だけを表示させています。

まずは忘れないうちにストロングパラメーターにstatusを追加しときましょう。

ストロングパラメーター


そして/controllers/blogs_controller.rbを編集します

def index
    @blogs = Blog.published.order("created_at DESC").page(params[:page]).per(10)
    @blogs_side = Blog.published.all.order("created_at DESC")
end

Blog.published.order("created_at DESC")ここで公開記事だけを検索して

order("created_at DESC")で記事の新しい順で表示させています。

page(params[:page]).per(10)ではページネーションの表示なので、今回は説明は省きます。

Blog.publishedでは
Blog.where(status: :published)
whereと同じ意味になります。

これはenum用のやり方らしいです。

僕の入っているコミュニティの会長である

@にゅ〜ぶるさんより教えていただきました。
ありがとうございます!

勝手にリンクを貼っときますwww

初学者の僕にも他の人にも、困ってたら声かけてくれるし、

わからないことを教えるのではなく、ヒントから教えてくれる、

とても優しい人です!

怒られたらリンク消しますwwww

これで公開記事の一覧ページは終了です。



次は、下書きページを作成します。


まずはルーティングを追加
config/routes.rbに追加
resources :blogs do
    collection do       追加
      get 'confirm'     追加
    end                       追加
end

collection doでアクションを追加します。

collectionはURLにidをつけません。
/blogs/confirm(.:format) 

member doだとidがつきます。
/blogs/:id/confirm(.:format) 

/controllers/blogs_controller.rbに戻ります。

アクションの追加
def confirm
    @blogs = Blog.draft.order("created_at DESC")
end

ここではdraft(下書き)一覧を表示させます。

あとは/views/blogs/confirm.html.erbファイルを作り、表示させれば完成です。


条件分岐で下書きはログインしてないと見れなくする


今のままだと全部の記事をURLを変えちゃえば見れちゃうことになります。

下書き記事なのに見られたら意味ないもんね!

それに存在しないIDをユーザーが調べたらエラーになります。

これを防ぐのにない頭で考えた結果、存在しないIDだとトップページにリダイレクトさせて

下書き記事はログインしてないと見れないようにしました。

controllerのshowアクションを編集します。
def show
    @blog = Blog.find_by(id: params[:id])

    if  @blog.nil?
      redirect_to root_path
    elsif @blog.draft?
      login_required
    end
end

条件分岐でif  @blog.nil?

ここでIDがnillなら redirect_to root_pathでトップページに飛ばします。

ちなみにBlog.find(id: params[:id])だとnillじゃなくてエラーが返ってくるので

find_byにしてnillを返してくるようにします。

elsif @blog.draft?

ここでnillでもなくてdraft(下書き)なら

login_requiredでログイン画面に飛ばしています。
    
def login_required
    redirect_to login_url unless current_user
end

current_userは、ここでは説明は省きます。

これで下書きはユーザーには見れないようにして見ました。

多分他にもっといい方法があるんだと思いますが、自分にはこの程度の処理しか考えつきませんでした!

次は入力フォームで公開記事か下書き記事か選択できるようにします。


セレクトボックスで選択できるようにした


まずは参考記事

こちら

gemの追加をします
gem 'enum_help'

/views/blogs/_form.html.erbに追加します
<div>
    <%= form.select :status, Blog.statuses.keys.map { |k| [t("enums.blog.status.#{k}"),k]} %>
</div

form.select :statusでstatusカラムをセレクトボックスで選択できるようにします。

Blog.statusesでenumのハッシュが取れます。
{"draft"=>0, "published"=>1} これですね

keysでそのうちのキーの部分を配列で取り出して

mapメソッドで

| k |にキーを代入していきます。
draftとpublishedです。

mapメソッドは、配列やハッシュの要素に対して1つずつ処理したい時に使います。

ハッシュに対してmapを使うことはできますが、その返り値はハッシュではなく配列になるようです。

 t でja.ymlの表記の通りに翻訳してくれるというメソッドらしいです。

config/locales/status_ja.yml
ja:
  enums:
    blog:
      status:
        draft: '下書き'
        published: '公開中'


("enums.blog.status.#{k}")ここは先ほどの翻訳が入ります
enums.blog.status.draftとpublishedが入りますね。

んで最後のkにkey(キー)が入ります。

これでセレクトボックスの選択に日本語で表示されます。
セレクト


<select name="blog[status]" id="blog_status">
  <option selected="selected" value="draft">下書き</option>
  <option value="published">公開中</option>
</select>

こーゆーことですね!!なるほどなるほど!!

これでもデーターベースに登録されるのは数字なんですね!!

これでenumを使った機能が完成しました。

少し長くなったけど、まとめだすと調べるのでより一層、理解力が増してきますね!

ブログって最高なメモ帳ですわw

ぜひ初学者の方達は、ブログでアウトプットしていきましょう!

ただ記事書くのにすげー時間かかります...

コード全然書けてねえええええ!!!!

次回はフォームに日付を登録できるようにすることと、タグ機能の追加をしてみようと思います。

実装完了後にブログにまとめるので少し日がかかるかもしれません。

少々お待ちを!

誰も待ってないけど...

むしろ全然人見に来ないけど...

でもそんなの関係ねえ!!
でもそんなの関係ねえ!!
でもそんなの関係ねえ!!

はい

おっぱry

次回


では、ばいなら〜

このブログサイトは初学者の僕が独学で
Ruby on Railsで作ったブログサイトです。 間違っている所もあるかもしれません。 あくまで参考程度にしていただけたらなと思います。 何かありましたらお問い合わせか、Twitter@ちょめこよりご連絡下さい。