質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

1回答

350閲覧

【Rails5】find_byのnil挙動について

ssk

総合スコア332

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2017/11/30 02:59

###前提・実現したいこと
has_onehas_manyの関係を持つユーザ情報を
CSVファイルのアップロードでDBに反映させたいです。

■リレーション

ruby

1#user.rb 2has_one :section, primary_key: "section_id", foreign_key: 'id' 3has_one :position, primary_key: "position_id", foreign_key: 'id' 4has_one :division, primary_key: "division_id", foreign_key: 'id' 5has_one :department, primary_key: "department_id", foreign_key: 'id' 6has_one :authority, primary_key: "authority_id", foreign_key: 'id' 7 8has_many :user_offices 9has_many :offices, through: :user_offices

CSV

1//インポートするCSVファイルのサンプルです。 2id,section_id,department_id,division_id,position_id,office_ids 31,飲食事業,東京部署,新宿支店,店長,新宿支店;渋谷支店

###発生している問題・エラーメッセージ
has_oneの関係
idに変換するのでfind_byで検索しています。

ruby

1table['section_id'] = Section.find_by(name: table['section_id']).id 2table['department_id'] = Department.find_by(name: table['department_id']).id 3table['division_id'] = Division.find_by(name: table['division_id']).id 4table['position_id'] = Position.find_by(name: table['position_id']).id

しかし、該当するnameがない場合
find_byの結果がnilとなり、そこで止まってしまいます。

ruby

1undefined method `id' for nil:NilClass

has_manyの関係
has_oneとあまり変わりませんが、配列を生成しています。
一応、動いてはいますが、他に良い方法がありましたら、助言をしていただきたいです。

ruby

1if table['office_ids'].present? 2 a = table['office_ids'].split(';') 3 table['office_ids'] = [] 4 5 a.each do |b| 6 table['office_ids'] << Office.find_by(name: b).id 7 end 8end

###補足情報(言語/FW/ツール等のバージョンなど)
・Rails (5.1.2)
参考サイト

has_oneの情報量って少ないですね、、
何卒、よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Section なら Section の,nameid の対照表が欲しいわけですよね。
CSV の 1 行ごとに検索するのも無駄なので,

rb

1section_name_to_id = Section.pluck(:name, :id).to_h

というハッシュを作っておくといいのではないでしょうか。

投稿2017/11/30 03:32

scivola

総合スコア2108

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ssk

2017/11/30 04:13

scivola様 引き続き、ありがとうございます。 仰る通り、ハッシュを作成することで対応できました。 find_byで取得できなかった場合、nilが入るので そのままnilが代入されると考えていました。 find_byで該当レコードがない場合はnilを返しでエラーになり ハッシュで該当キーがない場合はnilを返しエラーにはならない という理解でよろしいでしょうか?
scivola

2017/11/30 06:04

```rb Section.find_by(name: table['section_id']).id ``` の場合,当該レコードが存在しなければ `find_by` が `nil` を返し,`nil` の `id` を呼ぼうとして `NoMethodError` になります。 一方,ハッシュのデフォルト値(つまり存在しないキーに対する値)は,とくに指定しなければ `nil` です。
ssk

2017/11/30 06:06

ありがとうございます。 >の場合,当該レコードが存在しなければ `find_by` が `nil` を返し,`nil` の `id` を呼ぼうとして >`NoMethodError` になります。 理解することができました。 ご説明いただき、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問