🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby on Rails 6

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

Q&A

解決済

1回答

392閲覧

中間テーブルへ保存する際に何故かデータがnilになってしまいます

koya1613

総合スコア0

Ruby on Rails 6

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

0グッド

0クリップ

投稿2020/12/04 09:44

編集2020/12/04 09:49

前提・実現したいこと

【実現したいこと】
正常にデータを保存したいです。

【前提】
DM機能を実装しています。
userモデル
dmモデル
user_dmモデル(中間テーブル)
を作成し、送られてきたparams(二人分のユーザーid)をuser_dmsテーブルに保存することが目的です。

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

エラーは起きていないのですが、本来ならdmsテーブルとuser_dmsテーブルに保存されるはずのところで、保存が行われずに処理されてしまいます。
※binding.pryで確認したところ、保存するはずのdm_idがnilになっています。

9: def create => 10: binding.pry 11: dm = Dm.new(dm_params) 12: profile_user_id = dm.user_ids[0] #選んだユーザーのユーザーidを取得 13: profile_user_dm = UserDm.where(user_id: profile_user_id) #選んだユーザーのuser_dmsレコード情報を取得 14: profile_dm_ids = profile_user_dm.pluck(:dm_id) #選んだユーザーが持ってるdm_idを配列で取得 15: user_dm= UserDm.where(user_id: current_user.id) #現ユーザーのuser_dmsレコード情報を取得 16: dm_ids = user_dm.pluck(:dm_id) #現ユーザーが持ってるdm_idを配列で取得 17: @intersection = dm_ids & profile_dm_ids #現ユーザーと選んだユーザーが所属しているdm_id 18: # redirect_to dm_messages_path(@intersection) 19: redirect_to root_path 20: end [1] pry(#<DmsController>)> @dm = Dm.create(dm_params) User Load (0.5ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IN (2, 1) ↳ (pry):13:in `create' (0.2ms) BEGIN ↳ (pry):13:in `create' UserDm Exists? (0.4ms) SELECT 1 AS one FROM `user_dms` WHERE `user_dms`.`dm_id` IS NULL AND `user_dms`.`user_id` = 2 LIMIT 1 ↳ (pry):13:in `create' UserDm Exists? (0.5ms) SELECT 1 AS one FROM `user_dms` WHERE `user_dms`.`dm_id` IS NULL AND `user_dms`.`user_id` = 1 LIMIT 1 ↳ (pry):13:in `create' (0.2ms) ROLLBACK ↳ (pry):13:in `create' => #<Dm:0x00007fe53c2a63a8 id: nil, created_at: nil, updated_at: nil>

該当のソースコード

dmsコントローラー ←ここで保存処理を行っています。

ruby

1class DmsController < ApplicationController 2 3 def create 4 dm = Dm.new(dm_params) 5 dm.save 6 profile_user_id = dm.user_ids[0] #選んだユーザーのユーザーidを取得 7 profile_user_dm = UserDm.where(user_id: profile_user_id) #選んだユーザーのuser_dmsレコード情報を取得 8 profile_dm_ids = profile_user_dm.pluck(:dm_id) #選んだユーザーが持ってるdm_idを配列で取得 9 user_dm= UserDm.where(user_id: current_user.id) #現ユーザーのuser_dmsレコード情報を取得 10 dm_ids = user_dm.pluck(:dm_id) #現ユーザーが持ってるdm_idを配列で取得 11 @intersection = dm_ids & profile_dm_ids #現ユーザーと選んだユーザーが所属しているdm_id 12 redirect_to dm_messages_path(@intersection) 13 end 14 15 private 16 17 def dm_params 18 params.require(:dm).permit(user_ids: []) 19 end 20end 21

profilesのshowビュー ←ここのelse以下からユーザー二人分のidを送っています。

ruby

1 <div class="profile__direct"> 2 <% if current_page?(@user_profile) && @user_profile != nil%> 3 <%= link_to "DMルーム(現ユーザー)", dm_messages_path(:dm_id), class: :profile__btn %> 4 <% elsif !@intersection.empty?%> 5 <%= link_to "DMルーム", dm_messages_path(@intersection), class: :profile__btn %> 6 <% else %> 7 <%= form_with model: @dm, local: true do |f|%> 8 <input name="dm[user_ids][]" type="hidden" value=<%= @profile.user_id %>> 9 <input name="dm[user_ids][]" type="hidden" value=<%= current_user.id %>> 10 <%= f.submit "DMルーム(作成前)", class: :profile__btn %> 11 <% end %> 12 <% end %> 13 </div>

profilesコントローラー showアクション

ruby

1 def show 2 @profile = Profile.find(params[:id]) 3 profile_user_id = @profile.user_id #選んだユーザーのユーザーidを取得 4 profile_user_dm = UserDm.where(user_id: profile_user_id) #user_dmsテーブルに登録されている選んだユーザーの情報を取得 5 profile_dm_ids = profile_user_dm.pluck(:dm_id) #選んだユーザーが持ってるdm_idを配列で取得 6 user_dm= UserDm.where(user_id: current_user.id) 7 dm_ids = user_dm.pluck(:dm_id) #現ユーザーが持ってるdm_idを配列で取得 8 @intersection = dm_ids & profile_dm_ids #重なったdm_id 9 10 @dm = Dm.new 11 end 12

dmモデル

ruby

1class Dm < ApplicationRecord 2 has_many :messages 3 has_many :user_dms 4 has_many :users, through: :user_dms 5end 6

userモデル

ruby

1class User < ApplicationRecord 2 # Include default devise modules. Others available are: 3 # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable 4 devise :database_authenticatable, :registerable, 5 :recoverable, :rememberable, :validatable 6 has_one :plofile 7 has_many :messages 8 has_many :user_dms #中間テーブル 9 has_many :dms, through: :user_dms 10 11 with_options presence: true do 12 validates :first_name 13 validates :last_name 14 validates :first_name_ruby 15 validates :last_name_ruby 16 validates :phone_number 17 end 18 19 with_options format: {with: /\A[ぁ-んァ-ン一-龥]/} do 20 validates :first_name 21 validates :last_name 22 end 23 24 with_options format: {with: /\A[\p{hiragana} ー-&&[^ -~。-゚]]+\z/} do 25 validates :first_name_ruby 26 validates :last_name_ruby 27 end 28 29 validates :phone_number, format: {with: /\A\d{10}$|^\d{11}\z/} 30 31 validates :password, format: {with: /\A(?=.*?[a-z])(?=.*?\d)[a-z\d]/} 32end 33

user_dmモデル

ruby

1class UserDm < ApplicationRecord 2 belongs_to :user 3 belongs_to :dm 4 5 validates :dm_id, uniqueness: { scope: :user_id } 6end 7

試したこと

実はここを作っていた時はきちんと動いてくれていました。他の部分の開発を進めた後に再度確認したらこうなっておりました。
その間にやったことは、今回とは関係ないバリデーションを入れた事とテストコードを書いたくらいです。
念のため、全てコメントアウトして試しましたがやはり変わらずでした。

プログラミングの勉強を初めてまだ一ヶ月半程度なので、質問の仕方で至らない点もあるかと思いますが何卒ご容赦お願い致します。。

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

詳しいことは分からないのですが、macOSを使っております。最近買ったので恐らくバージョンは新しい方かと思います。

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

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

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

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

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

guest

回答1

0

自己解決

Userモデルのバリデーションが悪さをしていました。↓

validates :password, format: {with: /\A(?=.?[a-z])(?=.?\d)[a-z\d]/}

ユーザー登録時のバリデーションなのですが、何故かこれだけdmモデル もしくは user_dmモデル(中間テーブル)にも干渉していました。
一度コメントアウトして確認したつもりでしたが、これだけちょうど漏れていた様です..。
その他のバリデーションは問題ありませんでした。

理由は謎ですが一応解決しました
もし今回の原因が分かる方がいたら、コメントいただけると幸いです????‍♂️

投稿2020/12/04 10:26

編集2020/12/04 10:27
koya1613

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問