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

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

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

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

Q&A

解決済

2回答

277閲覧

undefined method `job' for nil:NilClassについて

hanahana1

総合スコア3

Ruby

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

0グッド

0クリップ

投稿2023/02/08 11:57

編集2023/02/09 00:21

前提

問い合わせ機能を搭載し、ある求人情報に対し、応募することができるサイトを作成中です。
応募者情報を入力し、フォームの送信をしたところでエラーが起きてしまい困っております。

実現したいこと

フォームの送信をすると、応募が完了すること。

発生している問題・エラーメッセージ

NoMethodError in OffersController#create undefined method `job' for nil:NilClass Extracted source (around line #3): class OfferMailerPreview < ActionMailer::Preview def offer_mail(offer) mail to: @offer.job.company.email, subject: "応募のお知らせ"  end end Rails.root: /Users/ユーザー名/projects/アプリ名 Application Trace | Framework Trace | Full Trace app/models/offer_mailer_preview.rb:3:in `offer_mail' app/controllers/offers_controller.rb:16:in `create' Request Parameters: {"authenticity_token"=>"VhrbUzzf6Cxz6gr/kVAPj0iEI5jb4oYZ9e1dUWgnCgWCF2MfE8ZaDBeD4/V5rwGm/irlfCuYVf6Fi4E9WVZicA==", "offer"=> {"last_name"=>"あ", "first_name"=>"あ", "email"=>"a@a", "age"=>"25", "prefecture_id"=>"2", "city"=>"十勝市十勝町", "house_number"=>"1丁目1番地", "building"=>"", "phone_number"=>"000-0000-0000", "academic_career"=>"a", "work_history"=>"a", "appeal"=>"a"}, "commit"=>"送信する", "job_id"=>"4"}

該当のソースコード

routes.rb

1Rails.application.routes.draw do 2 3 root to: "articles#index" 4 resources :articles, only: [:index, :show] 5 mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development? 6 resources :jobs do 7 resources :offers 8 end 9 10 devise_for :companies, controllers: { 11 registrations: 'companies/registrations', 12 sessions: 'companies/sessions', 13 } 14 15 16 devise_for :users, controllers: { 17 registrations: 'users/registrations', 18 sessions: 'users/sessions', 19 } 20 21 namespace :admin do 22 resources :articles, only: [:new, :create, :edit, :update, :destroy] 23 end 24end 25

offers_controller.rb

1class OffersController < ApplicationController 2 3 before_action :if_not_login, only: [:new] 4 5 6 def new 7 @job = Job.find(params[:job_id]) 8 @offer = Offer.new 9 end 10 11 def create 12 @job = Job.find(params[:job_id]) 13 @offer = Offer.new(offer_params) 14 if @offer.save 15 @offermailerpreview = OfferMailerPreview.new 16 @offermailerpreview.offer_mail(@offer).deliver 17 redirect_to 'create' 18 else 19 render :new 20 end 21 end 22 23 24 private 25 def offer_params 26 params.require(:offer).permit(:first_name, :last_name, :email, :age, :prefecture_id, :city, :house_number, 27 :building, :phone_number, :academic_career, :work_history, :appeal) 28 .merge(user_id: current_user.id, job_id: @job.id) 29 end 30 31 def if_not_login 32 unless user_signed_in? 33 redirect_to new_user_session_path 34 end 35 end 36end

offer_mailer_preview.rb

1class OfferMailerPreview < ActionMailer::Preview 2 def offer_mail(offer) 3 mail to: @offer.job.company.email, subject: "応募のお知らせ" 4 end 5end

試したこと

`job' for nil:NilClassとあるため、jobの直前にある@offer(応募者情報)が空であると考えました。
createアクションにbinding.pryを入れて確認したところ、@offerには情報が入っていました。併せて、offersコントローラー内の@offerの定義がされているかを確認したところ@offer = Offer.newの記述がありました。

定義自体はあるものの、やり方が間違っているという考えに至ったのですが、書き方が分からず困っております。
ルーティングに入れ子構造を取り入れているため、それが関係しているのでしょうか?
素人質問で申し訳ありませんが、ご助言をいただけますと幸いです。

補足情報(FW/ツールのバージョンなど)

jobモデル(求人情報管理のモデル)とofferモデル(応募者管理のモデル)は1対多の関係です。
companyモデル(求人情報を投稿した企業情報管理のモデル)とjobモデルは1対多の関係です。

offerモデルとcompanyモデル間にアソシエーションはありませんが、jobモデルを通してcompanyモデルに保存しているメールアドレスへ、応募者通知を行います。(offer_mailer_preview.rbの3行目に記載)

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

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

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

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

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

winterboum

2023/02/08 13:26

エラーメッセージと載ってるcodeが一致しません。 エラーが出たときのcodeにしてください。 OffersController の2〜6行に job など無いです。
guest

回答2

0

class OfferMailerPreview < ActionMailer::Preview def offer_mail(offer) mail to: @offer.job.company.email, subject: "応募のお知らせ"  end end

@offer を offer に

投稿2023/02/09 05:26

winterboum

総合スコア23423

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

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

0

自己解決

winterboum様、ご意見ありがとうございました!
ご意見を参考に下記の変更をしたところ、解決いたしました。拙い説明で恐縮です。

変更点①ファイル名の変更
実装の際に参照したサイトに沿って作ったはずですが、名前がoffer_mailer_preview.rbとなっていたのを、offer_mailer.rbへ変更しました。※これについては、②を調整すれば変えなくてもよかったかもしれないです。

変更点②Offersコントローラーのcreateアクション内でのメソッドの呼び出し
①のファイル名に合わせたのと、インスタンスの生成を無くしました。
※redirect_toの部分も変えていますが、今回のエラー内容とは直接関係なく、最終的なコードを記述しています。

ruby

1 def create 2 @job = Job.find(params[:job_id]) 3 @offer = Offer.new(offer_params) 4 if @offer.save 5 OfferMailer.offer_mail(@offer).deliver 6 redirect_to job_path(@job), notice: 'Offer was successfully created.' 7 else 8 render :new 9 end 10 end

変更点③offer_mailer.rb(旧:offer_mailer_preview.rb)で、変数の代入を追加
offer_mailer.rbはメールの送信先と件名の管理をするファイルです。メールの本文を記載しているファイルは別に存在しており、そこに変数を渡すために@offer = offerで変数の代入を行い、情報の受け渡しができるようにしました。

ruby

1class OfferMailer < ApplicationMailer 2 def offer_mail(offer) 3 @offer = offer 4 mail to: @offer.job.company.email, subject: "応募のお知らせ" 5 end 6end

補足:実装の際に参照したサイト
https://papa-programing.jp/rails-contacts-function/#%E3%83%A1%E3%83%BC%E3%83%AB%E3%81%8C%E5%B1%8A%E3%81%8F%E3%81%8B%E5%AE%9F%E8%A3%85%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B

投稿2023/02/09 07:28

hanahana1

総合スコア3

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.44%

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

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

質問する

関連した質問