0
0

More than 1 year has passed since last update.

カラム数に制限を設ける

Posted at

モデルに独自のバリデーションを書かずにコントローラー内で処理をする方法を考えてみました。

環境

ruby 2.6.5
rails 5.2
Mac OS

必要な gem 無し

テーブルは
Post : comment が 1対多になってます。

実装したいこと

userの投稿にたとえばコメントがあったとして、そのコメント数を制限する。
みたいな感じの機能です。

大雑把な流れとして
userが投稿詳細ページからコメントを追加

createアクションが動く

投稿に対するコメント数が条件より少ない場合、そのまま作成され
条件を超えた場合はflashと共に元のページにリダイレクトさせる

何を使うか

コメントのカラムには自身が持つ"id"の他に外部キーとして"post_id"を持たせています。
これによって「post_idがn番のコメント」と表現することができます。
今回数えたいのはまさにこのpost_idです。

情報を取得するメソッドはたくさんあるのでそのなかから最適なものを探します。


  • all
  • find または find_by
  • select
  • where

くらいでしょうか。

allはモデルの情報全て持ってくるし、findはidのレコード持ってくるだけだし、find_byも同じく使わないし、selectは指定したカラムの情報を全て返すし、みたいな感じでいろいろ試していったところ
「where」が1番適していました。

各メソッドの書き方
 ALL:
  @posts = Post.all
  インスタンス  =  モデル名

 FIND:
  @post = Post.find(id)
    #引数には必要なレコードのidを指定

 FIND_BY:
  @post = Post.find_by(email: params[:email])  ←他にも指定できます。
    #カラムと実際の値を記載する
 SELECT:
  @comment = Post.select(:post_id)
   #カラムを指定

 WHERE:
  @comments = Post.where(post_id: params[:post_id])
  #カラムと実際の値を記載

みてわかる通り、find_byは1件のレコードを返すのに対して、whereは指定された値のカラムを全て返します。

Commentモデル内に10個くらいデータがあったとして、そのうちpost_idが"3"のものがいくつあるか知りたい場合は

  @comments = Comment.where(post_id: 3)

とすることでpost_idが3のものが帰ってきます。

注意としてはここで返ってきた情報に対して、他のカラムを参照したりすることはできないです。

あくまでpost_idが3のものを表示しているだけなので

findやfind_byなどはidに対応するレコードを持ってくるので

  @user = User.find(1)

  @user.id
  @user.nickname
  @user.age

こう書いてカラムを呼び出すことができます。

実装

さっき書いた

comments = Comment.where(post_id: post_id)

これをコントローラーのcreateアクションに書いて

def create
  @comment = Comment.new(comment_params)
  comments = Comment.where(post_id: params[:post_id])

  if comments.count < 10

    if @comment.save?
      flash[:notice] = "成功しました"
      redirect_to root_path
    else
      flash[:alert] = "失敗しました"
      redirect_to post_path(@post)
   end

  else
    flash[:alert] = "これ以上追加できません"
    redirect_to post_path(@post)

  end
end

こんな感じで10件まで追加できるようになりました!

0
0
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
0
0