ruby_of_pokemon
@ruby_of_pokemon

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

[Rails][heroku]本番環境でNoMethodError (undefined method `[]' for nil:NilClass)が出る

解決したいこと

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

1Answer

settings.ymlを.gitignoreに設定していたためでした。。。w
エラー文の前ばかり気にしていて、後の方全然見ていなかった。。。

0Like

Your answer might help someone💌