QA@IT
«回答へ戻る

行ロックでなくテーブルのロックが必要そうだったので修正

1137
 end
 ```
 
-ただし、上記の例だと、ほぼ同時にコメントが投稿された場合に validation を通ってしまう恐れがあるので、厳密にチェックするなら行ロックなどが必要です。
+ただし、上記の例だと、ほぼ同時にコメントが投稿された場合に validation を通ってしまう恐れがあるので、厳密にチェックするならおそらくテーブルのロックが必要です。

comment.rb に validate クラスメソッドを使って書けばよいと思います。

class Comment < ActiveRecord::Base
  belongs_to :article

  # 作成時 (create) のみ実行
  validate on: :create do
    # 既存のコメント数を調べて...
    if article && article.comments.count > 5
      # validation に失敗したら errors.add を呼ぶ
      errors.add(:article, :has_too_many_comments)
    end
  end
end

ブロックでなくメソッドで書く事もできます。

class Comment < ActiveRecord::Base
  belongs_to :article

  # 第 1 引数にメソッド名をシンボルで指定
  validate :article_has_too_many_comments, on: :create

  def article_has_too_many_comments
    if article && article.comments.count > 5
      errors.add(:article, :has_too_many_comments)
    end
  end
end

ただし、上記の例だと、ほぼ同時にコメントが投稿された場合に validation を通ってしまう恐れがあるので、厳密にチェックするならおそらくテーブルのロックが必要です。

comment.rb に validate クラスメソッドを使って書けばよいと思います。

```ruby
class Comment < ActiveRecord::Base
  belongs_to :article

  # 作成時 (create) のみ実行
  validate on: :create do
    # 既存のコメント数を調べて...
    if article && article.comments.count > 5
      # validation に失敗したら errors.add を呼ぶ
      errors.add(:article, :has_too_many_comments)
    end
  end
end
```

ブロックでなくメソッドで書く事もできます。

```ruby
class Comment < ActiveRecord::Base
  belongs_to :article

  # 第 1 引数にメソッド名をシンボルで指定
  validate :article_has_too_many_comments, on: :create

  def article_has_too_many_comments
    if article && article.comments.count > 5
      errors.add(:article, :has_too_many_comments)
    end
  end
end
```

ただし、上記の例だと、ほぼ同時にコメントが投稿された場合に validation を通ってしまう恐れがあるので、厳密にチェックするならおそらくテーブルのロックが必要です。

回答を投稿

comment.rb に validate クラスメソッドを使って書けばよいと思います。

class Comment < ActiveRecord::Base
  belongs_to :article

  # 作成時 (create) のみ実行
  validate on: :create do
    # 既存のコメント数を調べて...
    if article && article.comments.count > 5
      # validation に失敗したら errors.add を呼ぶ
      errors.add(:article, :has_too_many_comments)
    end
  end
end

ブロックでなくメソッドで書く事もできます。

class Comment < ActiveRecord::Base
  belongs_to :article

  # 第 1 引数にメソッド名をシンボルで指定
  validate :article_has_too_many_comments, on: :create

  def article_has_too_many_comments
    if article && article.comments.count > 5
      errors.add(:article, :has_too_many_comments)
    end
  end
end

ただし、上記の例だと、ほぼ同時にコメントが投稿された場合に validation を通ってしまう恐れがあるので、厳密にチェックするなら行ロックなどが必要です。

comment.rb に validate クラスメソッドを使って書けばよいと思います。

```ruby
class Comment < ActiveRecord::Base
  belongs_to :article

  # 作成時 (create) のみ実行
  validate on: :create do
    # 既存のコメント数を調べて...
    if article && article.comments.count > 5
      # validation に失敗したら errors.add を呼ぶ
      errors.add(:article, :has_too_many_comments)
    end
  end
end
```

ブロックでなくメソッドで書く事もできます。

```ruby
class Comment < ActiveRecord::Base
  belongs_to :article

  # 第 1 引数にメソッド名をシンボルで指定
  validate :article_has_too_many_comments, on: :create

  def article_has_too_many_comments
    if article && article.comments.count > 5
      errors.add(:article, :has_too_many_comments)
    end
  end
end
```

ただし、上記の例だと、ほぼ同時にコメントが投稿された場合に validation を通ってしまう恐れがあるので、厳密にチェックするなら行ロックなどが必要です。