1995年の今日、PS1版の「幻想水滸伝」が発売

1995年の今日、PS1版の「幻想水滸伝」が発売されました。コナミの公式Twitterアカウントでも紹介されています。

来年の2020年で25周年となる幻水I。何らかの動きがあると嬉しいですね。

2020年の2月は、「幻水I・II」、「幻水V」、「紡時」の発売月であり、「2020 年の 2 月」ということで 2 続きになって何かと語呂がいいことに気づきました。

Rails (Active Record) で複数のレコードを一括登録する際の #new 〜 #save と #create の違い

結論

  • #create の場合は引数に配列を取ることができる
  • #new 〜 #save の場合は、#new で引数に配列を取った後に、each で回して個別に #save する

具体例

users テーブルに 2つ のレコードを保存する例を考えてみます。

#create を用いる場合

User.create(
  [
    {
      name: 'taro',
      age: 20
    },
    {
      name: 'hanako',
      age: 25
    }
  ]
)

#new 〜 #save を用いる場合

users = User.new(
  [
    {
      name: 'taro',
      age: 20
    },
    {
      name: 'hanako',
      age: 25
    }
  ]
)

users.each do |user|
  user.save
end

参考

Bulk Insert をするための activerecord-import という gem もあります。

github.com

Visual Studio Code で Ruby Solargraph 拡張機能を使っている際に、Rails の require 記述に対して RequireNotFound エラーが出る場合の対処方法

状況

こういうやつです。

gyazo.com

結論

  • .solargraph.yml を Rails のルートに作成し、そこの除外設定を書きます
    • 具体的な記述内容は以下のとおりになります
include:
  - '**/*.rb'
exclude:
  - vendor/**/*
  - '.bundle/**/*'
reporters:
  - rubocop
require:
  - actioncable
  - actionmailer
  - actionpack
  - actionview
  - activejob
  - activemodel
  - activerecord
  - activestorage
  - activesupport

なぜこれでいいのか

  • VS Code の Solargraph 拡張機能における require_not_found の実装が甘い らしく、require_not_found をチェックの対象(== reporters)から意図的に除外することで、このエラーは出なくなるから
    • 言い換えれば、reporters として rubocop ということであり、その内容を .solargraph.yml に明示的に記述している
  • exclude というキーと値をを指定しているのは、gem の中身まで solagraph の対象とされてしまうと重くなってしまうから

Rails で PostgreSQL を使っている際に #create すると UniqueViolation エラーが出る場合

原因の一つとして考えられるもの

id を明示的に指定してレコードを作成した履歴がありませんか? seed のデータを投入する場合にやりがちです。

たとえば、以下のようにして user のレコードを作った場合です。

User.create(
  id: 100,
  name: 'taro',
  age: 24
)

なぜエラーになるのか

id を明示的に指定してレコードを作った場合は、PostgreSQL の内部で自動採番が行われないので、 Active Record が自動で id を割り当てる際にバッティングするから*1

どうすればいいか

レコードの追加の際には id を明示的に指定しないようにします。もし id を明示的に指定してレコードを追加したい場合には、レコード追加後に手動で採番を調整しましょう*2

わかりやすい記事を書いてくださっている方がいらっしゃいます。

eienshinjin.hatenablog.com

エラーメッセージの例

ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint ......

*1:Active Record が自動で id を割り当てる際には、PostgreSQL の内部情報を見るから

*2:ただ、Active Record を使う限りでは id を明示的に指定する場面は少ないと思います

Rails で #create した際に ROLLBACK が出た場合の理由が知りたい(デバッグしたい、エラーログが見たい)とき

結論

以下の2つのどちらかの方法を使いましょう*1

方法1. #new してから valid? で検証し、#errors でログを出す

#create をいきなり使うと、エラーがなかった場合には実際にレコードが作られてしまうので、通常はこちらを使うといいと思います。

以下、users というテーブルにレコードを作成する場合を例にします。作成の際に email: 'foobar@example.com' というように email カラムに値を指定します。しかし、「passwordpassword_confirmation にも値が必要である」という理由でレコードが正しく作成されない状況を想定しています。

また、以下は pry 上での操作です。

> user = User.new(email: 'foobar@example.com')
(省略)
> user.valid?
=> false
> user.errors
(省略)
 @messages=
  {:password=>["can't be blank"],
   :password_confirmation=>["can't be blank"]}>

方法2. #create してから logger でログを出す

いざ #create したら ROLLBACK された場合、以下の方法でもよいでしょう*2

> user = User.create(email: 'foobar@example.com')
(省略)
   (0.1ms)  rollback transaction
> Rails.logger.debug(user.errors)
(省略)@messages={:password=>["can't be blank"], :password_confirmation=>["can't be blank"]}, (後略)

*1:他にもあると思います

*2:ただ、正常に #create されると実際にレコードが作成されることには注意です

Powered by はてなブログ