[Rails][heroku]本番環境でNoMethodError (undefined method `[]' for nil:NilClass)が出る
Q&A
Closed
解決したいこと
herokuにデプロイしたアプリで、データの新規作成時に
NoMethodError (undefined method '[]' for nil:NilClass)
が出るのでそのエラーを直したいです。
開発環境ではエラーが起こらずうまく保存できるのですが、本番ではエラーが発生する状況です。
環境
Rails 7.0.4.3
ruby 3.1.4
heroku
postgresql 16.2
発生している問題・エラー
herokuのログ
Jun 24 07:31:01 sash-memo-heroku-app app/web.1 I, [2024-06-24T14:31:01.192593 #2] INFO -- : [2baf6b2b-b6cd-4184-ab18-980a8296e476] Started POST "/inner_sashes/new_append_room" for 110.66.59.38 at 2024-06-24 14:31:01 +0000
Jun 24 07:31:01 sash-memo-heroku-app app/web.1 I, [2024-06-24T14:31:01.193701 #2] INFO -- : [2baf6b2b-b6cd-4184-ab18-980a8296e476] Processing by InnerSashesController#new_append_room as TURBO_STREAM
Jun 24 07:31:01 sash-memo-heroku-app app/web.1 I, [2024-06-24T14:31:01.193768 #2] INFO -- : [2baf6b2b-b6cd-4184-ab18-980a8296e476] Parameters: {"authenticity_token"=>"[FILTERED]", "inner_sash"=>{"room"=>"t", "width_up_size"=>"4", "width_down_size"=>"43", "width_middle_size"=>"4", "height_left_size"=>"3", "height_right_size"=>"3", "height_middle_size"=>"3", "height_frame_depth"=>"3", "width_frame_depth"=>"3"}, "commit"=>"追加"}
Jun 24 07:31:01 sash-memo-heroku-app app/web.1 D, [2024-06-24T14:31:01.201288 #2] DEBUG -- : [2baf6b2b-b6cd-4184-ab18-980a8296e476] User Load (4.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
Jun 24 07:31:01 sash-memo-heroku-app app/web.1 D, [2024-06-24T14:31:01.202866 #2] DEBUG -- : [2baf6b2b-b6cd-4184-ab18-980a8296e476] SiteMemo Load (1.0ms) SELECT "site_memos".* FROM "site_memos" WHERE "site_memos"."kind" = $1 AND "site_memos"."site_id" = $2 LIMIT $3 [["kind", 0], ["site_id", 1], ["LIMIT", 1]]
Jun 24 07:31:01 sash-memo-heroku-app app/web.1 I, [2024-06-24T14:31:01.206673 #2] INFO -- : [2baf6b2b-b6cd-4184-ab18-980a8296e476] Completed 500 Internal Server Error in 13ms (ActiveRecord: 5.7ms | Allocations: 3443)
Jun 24 07:31:01 sash-memo-heroku-app app/web.1 F, [2024-06-24T14:31:01.207310 #2] FATAL -- : [2baf6b2b-b6cd-4184-ab18-980a8296e476]
Jun 24 07:31:01 sash-memo-heroku-app app/web.1 [2baf6b2b-b6cd-4184-ab18-980a8296e476] NoMethodError (undefined method `[]' for nil:NilClass):
Jun 24 07:31:01 sash-memo-heroku-app app/web.1 [2baf6b2b-b6cd-4184-ab18-980a8296e476]
Jun 24 07:31:01 sash-memo-heroku-app app/web.1 [2baf6b2b-b6cd-4184-ab18-980a8296e476] app/validators/size_validator.rb:5:in `validate_each'
Jun 24 07:31:01 sash-memo-heroku-app app/web.1 [2baf6b2b-b6cd-4184-ab18-980a8296e476] app/controllers/inner_sashes_controller.rb:19:in `new_append_room'
該当するソースコード
inner_sashes_controller.rb
before_action :set_site_memo, only:[:new_step2, :new_append_room]
def new_step2
# fields_forを使わないのはinner_sashのフォームは一つにしたいため
@inner_sash = InnerSash.new
@site_memo.update_status(action: action_name)
end
def new_append_room
@inner_sash = @site_memo.inner_sashes.build(inner_sash_params)
@inner_sash = InnerSash.new if @inner_sash.save ← ここの処理時にエラーが起きる
# 保存失敗したら、パラメーターを元に作ったインスタンス返す
# new_append_room.turbo_stream.erbへ
end
def inner_sash_params
params.require(:inner_sash).permit(:room, :number_of_shoji, :width_up_size, :width_down_size, :width_middle_size,
:height_left_size, :height_middle_size, :height_right_size, :width_frame_depth, :height_frame_depth,
:sash_type, :color, :number_of_shoji, :hanging_origin, :is_flat_bar, :is_adjust,
:glass_thickness, :glass_kind, :glass_color, :is_low_e, :key_height, :middle_frame_height,
:template, photos_attributes: [:id, :file_name, :_destroy])
end
def set_site_memo
@site_memo = SiteMemo.find_by(kind: 'inner_sash', site_id: session[:site_id])
end
settings.yml
limit_size:
digits: 5
child:
none: 0
size_validator.rb
class SizeValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
return if value.blank?
record.errors.add(attribute, 'は5桁以内で入力してください') if value.to_s.length > Settings.limit_size[:digits]
end
end
inner_sash.rb
class InnerSash < ApplicationRecord
attr_accessor :template
belongs_to :site_memo
has_many :photos, dependent: :destroy
accepts_nested_attributes_for :photos, allow_destroy: true
enum color: { c_undecided: 0, white: 1}
enum sash_type: { t_undecided: 0, sliding: 1, opening: 2}
enum hanging_origin: { h_undecided: 0, right: 1, left: 2}
enum glass_color: { gc_undecided: 0, green: 1, clear: 2}
enum glass_thickness: { gt_undecided: 0, single: 1, double: 2}
enum glass_kind: { gk_undecided: 0, transparent: 1, hazy: 2}
enum order: { unordered: 0 , ordered: 1 }
validates :room, presence: true, length: { maximum:15 }
validates :width_up_size, presence: true, size: true
validates :width_down_size, presence: true, size: true
validates :width_middle_size, presence: true, size: true
validates :height_left_size, presence: true, size: true
validates :height_middle_size, presence: true, size: true
validates :height_right_size, presence: true, size: true
validates :width_frame_depth, presence: true, size: true
validates :height_frame_depth, presence: true ,size: true
validates :color, presence: true
validates :is_flat_bar, inclusion: {in: [true, false]}
validates :key_height, presence: true
validates :sash_type, presence: true
validates :number_of_shoji, presence: true
validates :middle_frame_height, presence: true
validates :is_adjust, inclusion: {in: [true, false]}
validates :hanging_origin, presence: true
validates :glass_color, presence: true
validates :glass_kind, presence: true
validates :glass_thickness, presence: true
validates :is_low_e, inclusion: {in: [true, false]}
def previous
InnerSash.eager_load(site_memo: :site).where(site: {id: self.site_memo.site_id}).where("inner_sashes.id<?", self.id).order(id: :desc).first
end
def next
InnerSash.eager_load(site_memo: :site).where(site: {id: self.site_memo.site_id}).where("inner_sashes.id>?", self.id).order(id: :asc).first
end
def destroy_last_with(site_memo:)
self.transaction do
self.destroy
site_memo.destroy if site_memo.inner_sashes.size == Settings.child[:none]
end
end
end
自分で試したこと
-
inner_sashes_controller.rbのストロングパラメータを色々いじる
(photo_attributes消したり、とりあえず保存できるように必要な数だけにした。) -
herokuにRAILS_MASTER_KEYの設定
-
new_append_roomの処理を変えた
inner_sashes_controller.rb
# 最初はこうでした
def new_append_room
@inner_sash = InnerSash.new(inner_sash_params.merge(site_memo_id: @site_memo_id))
@inner_sash = InnerSash.new if @inner_sash.save ← ここの処理時にエラーが起きる
# 保存失敗したら、パラメーターを元に作ったインスタンス返す
# new_append_room.turbo_stream.erbへ
end
#同じ変数使うのよくないかもと思い試しに下のようにしたがダメだった
def new_append_room
inner_sash = InnerSash.new(inner_sash_params.merge(site_memo_id: @site_memo_id))
@inner_sash = InnerSash.new if inner_sash.save ← ここの処理時にエラーが起きる
# 保存失敗したら、パラメーターを元に作ったインスタンス返す
# new_append_room.turbo_stream.erbへ
end
疑問に思うこと
- なぜ開発環境でエラーが出てないのに本番ではエラーが出るのか
- save時にエラーが発生するのだけど、
undefined method '[]' for nil:NilClass
に該当するコードが見当たらない - 他のコントローラーで新規作成した時は無事データを保存できたこと。
色々調べたのですが、有力な情報が全然出てこなかったです。何かわかる方がいれば意見や、参考になる記事を教えていただきたいです。
おそらくコントローラーの処理時に何かおかしい処理が起きているのだろうと思い、とりあえず載せましたが、viewやmodelのコードも見たいという方がいれば教えてください。
またこういうコードの書き方の方がいいよなど教えて頂けたら助かります。
よろしくお願いします。
0