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

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

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

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

Ruby on Rails

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

Q&A

解決済

1回答

1651閲覧

関連付けしたモデルのデータ削除に関して undefined method for nil:NilClass

stwebyy

総合スコア14

Ruby

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

Ruby on Rails

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

0グッド

0クリップ

投稿2018/05/02 00:39

現在、各ユーザーに毎に情報を登録できるアプリを開発しています。
ユーザー機能はdeviseを使用しています。
今実装したい内容が、ユーザーを削除すると、そのユーザーが登録した情報も一緒に消えるという機能を実装したいと考えています。
そこで、userモデルとcompanyモデルを1対多の関係で関連付けをしました。
また、companyコントローラーにdestroyアクションを追加し、開いている情報ページの単体の削除機能は実装いたしました。
次にuserコントローラーにもdestroyアクションを追加し、削除を行ったところ、

undefined method `name' for nil:NilClass

と出てしまいました。
モデルの記述も問題ないと思われるため、各コントローラーのdestroyアクションの記述が問題だと思うのですが、解決方法がわかりません。
原因を調べるためにログを確認すると以下の内容が出ていました。

sql

1Started DELETE "/users/2" for 127.0.0.1 at 2018-05-02 09:21:40 +0900 2Processing by UsersController#destroy as HTML 3 Parameters: {"authenticity_token"=>"I7m3KAKxOINmRXurMXIR9euoW5hoIDT5ye8OSXggyfo=", "id"=>"2"} 4 User Load (1.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 ORDER BY `users`.`id` ASC LIMIT 1 5 User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1 6 (0.1ms) BEGIN 7 8 Company Load (0.4ms) SELECT `companies`.* FROM `companies` WHERE `companies`.`user_id` = 2 9 SQL (1.4ms) DELETE FROM `companies` WHERE `companies`.`id` = 3 10 (15.3ms) ROLLBACK 11Completed 500 Internal Server Error in 46ms 12 13NoMethodError (undefined method `name' for nil:NilClass): 14 app/controllers/users_controller.rb:9:in `destroy'

このcompaniesは、
user.id = companies.user_id
となっているため、user.id = 2のデータを削除するのであれば、最後のsql文が

sql

1DELETE FROM `companies` WHERE `companies`.`user_id` = 2

とならなくてはいけないはずですが、controllerをいじっても変わってくれません・・・。
5〜6時間以上ググったりしてみたのですが、解決の見込みが立っておりません。
どなたか原因、対策を教えていただけますでしょうか?
よろしくお願いいたします。

ruby

1user.rb 2 3class User < ActiveRecord::Base 4 attr_accessor :login 5 has_many :companies, dependent: :destroy 6 validates :name, presence: true, length: { maximum: 50 } 7 # Include default devise modules. Others available are: 8 # :confirmable, :lockable, :timeoutable and :omniauthable 9 devise :database_authenticatable, :registerable, 10 :recoverable, :rememberable, :trackable, :validatable, 11 authentication_keys: [:login] 12 13 def self.find_for_database_authentication(warden_conditions) 14 conditions = warden_conditions.dup 15 if login = conditions.delete(:login) 16 where(conditions.to_h).where(["lower(name) = :value OR lower(email) = :value", { :value => login.downcase }]).first 17 elsif conditions.has_key?(:name) || conditions.has_key?(:email) 18 where(conditions.to_h).first 19 end 20 end 21end 22

ruby

1company.rb 2 3class Company < ActiveRecord::Base 4 belongs_to :user 5 validates :nameco, presence: true, length: { maximum: 40 } 6 validates :business, :wish, presence: true, length: { maximum: 300 } 7 validates :recruit, presence: true, length: { maximum: 100 } 8 validates :income, :employee, numericality: { greater_than:0 } 9 validates :wishpoint, presence: true, numericality: { less_than: 6, greater_than:0 } 10 validates :remarks, length: { maximum: 200 } 11end 12

ruby

1users.controller.rb 2 3class UsersController < ApplicationController 4 before_action :authenticate_user! 5 def show 6 @user=User.find(params[:id]) 7 end 8 9 def destroy 10 # TODO ここでエラー発生 11 User.find(params[:id]).destroy 12 flash[:success] = "削除しました。" 13 redirect_to root_path 14 end 15end 16

ruby

1companies.controller 2 3class CompaniesController < ApplicationController 4 before_action :authenticate_user! 5 helper_method :sort_column, :sort_direction 6 def new 7 @company = Company.new 8 @submit = false 9 end 10 11(略) 12. 13. 14. 15. 16 17 18 def destroy 19 Company.find(params[:id]).destroy 20 flash[:success] = "削除しました。" 21 redirect_to companies_path 22 end 23 24 def show 25 @company = Company.find(params[:id]) 26 @id = current_user.id 27 28 end 29 30 def index 31 @companies = Company.where(user_id: current_user.id).order(sort_column + ' ' + sort_direction) 32 end 33 34. 35. 36. 37. 38(略) 39 40 private 41 42 def company_params 43 params.require(:company).permit(:salesname, :nameco, :business, :recruit, :income, :employee, :wish, :wishpoint, :advance, :remarks, :user_id) 44 end 45 46. 47. 48. 49. 50(略) 51

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

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

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

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

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

guest

回答1

0

ベストアンサー

エラーの原因はちょっとわからないのですが、SQLがDELETE FROM `companies` WHERE `companies`.`id` = 3となるのは正しい動作のようです。
dependent: :destroyとした場合、Userを削除するとCompany#destroyが毎回呼ばれるようです。dependent: :delete_allとすると、ActiveRecordを通さず直接SQLが発行されるので、仰るようなSQLになると思います(試してませんが)。

投稿2018/05/02 04:43

takara7

総合スコア107

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問