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

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

詳細はこちら
Ruby

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

Ruby on Rails

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

Q&A

解決済

1回答

1544閲覧

Railsで、中間テーブルのカラムに他のテーブルからカラムの値を参照したい

DaikiUTT

総合スコア5

Ruby

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

Ruby on Rails

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

0グッド

0クリップ

投稿2019/12/29 17:56

編集2020/01/02 03:10

前提・実現したいこと

Tagモデル、ListモデルをTagListモデルを中間テーブルとして関連付けしています。
ログイン中のユーザーの作成したもののみをtag_lists_controllerで@tag_lists = TagList.where(user_id: current_user.id)とすることでtaglistsの一覧ページで表示させたいのですが、
コマンドラインで確認したところTagList.user_idがnilになっているためうまくできません。
なので、今回実現したいことはTagList.user_idにcurrent_user.idを代入できるようにすることです。

各テーブルのカラムは以下のようになっています。

Ruby

1create_table "tags", force: :cascade do |t| 2 t.string "content" 3 t.datetime "created_at", null: false 4 t.datetime "updated_at", null: false 5 t.integer "user_id" 6end 7 8create_table "lists", force: :cascade do |t| 9 t.string "content" 10 t.datetime "created_at", null: false 11 t.datetime "updated_at", null: false 12 t.integer "user_id" 13 t.date "start_time" 14end 15 16create_table "tag_lists", force: :cascade do |t| 17 t.integer "tag_id" 18 t.integer "list_id" 19 t.datetime "created_at", null: false 20 t.datetime "updated_at", null: false 21 t.integer "user_id" 22 t.index ["list_id"], name: "index_tag_lists_on_list_id" 23 t.index ["tag_id"], name: "index_tag_lists_on_tag_id" 24end 25 26create_table "users", force: :cascade do |t| 27 t.string "email", default: "", null: false 28 t.string "encrypted_password", default: "", null: false 29 t.string "reset_password_token" 30 t.datetime "reset_password_sent_at" 31 t.datetime "remember_created_at" 32 t.datetime "created_at", null: false 33 t.datetime "updated_at", null: false 34 t.index ["email"], name: "index_users_on_email", unique: true 35 t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true 36end 37

また、各モデルのアソシエーションは以下のようになっています。

Ruby

1class Tag < ApplicationRecord 2 belongs_to :user, optional: true 3 has_many :tag_lists, dependent: :destroy 4 has_many :lists, :through => :tag_lists 5end 6 7class List < ApplicationRecord 8 belongs_to :user, optional: true 9 has_many :tag_lists, dependent: :destroy 10 has_many :tags, :through => :tag_lists 11end 12 13class TagList < ApplicationRecord 14 belongs_to :user, optional: true 15 belongs_to :tag, optional: true 16 belongs_to :list, optional: true 17end 18 19class User < ApplicationRecord 20 has_many :diaries 21 has_many :tags 22 has_many :lists 23 has_many :tag_lists 24end

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

エラーメッセージは表示されていません。
コマンドラインでrails cをしてTagList.allと入力するとuser_id: nilと表示されます。
本来はこのnilの部分にcurrent_user.id(ログイン中のユーザーのid)が入るようにしたいです。

該当のソースコード

Ruby

1class TagListsController < ApplicationController 2 before_action :set_tag_list, only: [:show, :edit, :update, :destroy] 3 4 def index 5 @tag_lists = TagList.where(user_id: current_user.id) 6 end 7 8 # GET /tag_lists/1 9 # GET /tag_lists/1.json 10 def show 11 end 12 13 # GET /tag_lists/new 14 def new 15 @tag_list = TagList.new 16 end 17 18 # GET /tag_lists/1/edit 19 def edit 20 end 21 22 # POST /tag_lists 23 # POST /tag_lists.json 24 def create 25 @tag_list = TagList.new(tag_list_params) 26 27 @tag_list.user_id = current_user.id 28 #@tag_list.user_id = tag_list.list.user_id 29 30 respond_to do |format| 31 if @tag_list.save 32 format.html { redirect_to @tag_list, notice: 'Tag list was successfully created.' } 33 format.json { render :show, status: :created, location: @tag_list } 34 else 35 format.html { render :new } 36 format.json { render json: @tag_list.errors, status: :unprocessable_entity } 37 end 38 end 39 end 40 41 # PATCH/PUT /tag_lists/1 42 # PATCH/PUT /tag_lists/1.json 43 def update 44 respond_to do |format| 45 if @tag_list.update(tag_list_params) 46 format.html { redirect_to @tag_list, notice: 'Tag list was successfully updated.' } 47 format.json { render :show, status: :ok, location: @tag_list } 48 else 49 format.html { render :edit } 50 format.json { render json: @tag_list.errors, status: :unprocessable_entity } 51 end 52 end 53 end 54 55 # DELETE /tag_lists/1 56 # DELETE /tag_lists/1.json 57 def destroy 58 @tag_list.destroy 59 respond_to do |format| 60 format.html { redirect_to tag_lists_url, notice: 'Tag list was successfully destroyed.' } 61 format.json { head :no_content } 62 end 63 end 64 65 private 66 # Use callbacks to share common setup or constraints between actions. 67 def set_tag_list 68 @tag_list = TagList.find(params[:id]) 69 end 70 71 # Never trust parameters from the scary internet, only allow the white list through. 72 def tag_list_params 73 params.require(:tag_list).permit(:tag_id, :list_id) 74 end 75end

Ruby

1class ListsController < ApplicationController 2before_action :set_list, only: [:show, :edit, :update, :destroy] 3 4# GET /lists 5# GET /lists.json 6def index 7 8#@list = List.find(params[:id]) 9 10@lists= List.where(user_id: current_user.id).order("start_time ASC") 11end 12 13# GET /lists/1 14# GET /lists/1.json 15def show 16end 17 18# GET /lists/new 19def new 20@list = List.new 21end 22 23# GET /lists/1/edit 24def edit 25end 26 27# POST /lists 28# POST /lists.json 29def create 30@list = List.new(list_params) 31 32@list.user_id = current_user.id 33 34#@list.tag_list.user_id = current_user.id 35 36 37respond_to do |format| 38if @list.save 39format.html { redirect_to @list, notice: 'List was successfully created.' } 40format.json { render :show, status: :created, location: @list } 41else 42format.html { render :new } 43format.json { render json: @list.errors, status: :unprocessable_entity } 44end 45end 46end 47 48# PATCH/PUT /lists/1 49# PATCH/PUT /lists/1.json 50def update 51respond_to do |format| 52if @list.update(list_params) 53format.html { redirect_to @list, notice: 'List was successfully updated.' } 54format.json { render :show, status: :ok, location: @list } 55else 56format.html { render :edit } 57format.json { render json: @list.errors, status: :unprocessable_entity } 58end 59end 60end 61 62# DELETE /lists/1 63# DELETE /lists/1.json 64def destroy 65@list.destroy 66respond_to do |format| 67format.html { redirect_to tag_lists_url, notice: 'List was successfully destroyed.' } 68format.json { head :no_content } 69end 70end 71 72private 73# Use callbacks to share common setup or constraints between actions. 74def set_list 75@list = List.find(params[:id]) 76end 77 78# Never trust parameters from the scary internet, only allow the white list through. 79def list_params 80params.require(:list).permit(:content,:start_time, tag_ids:[]) 81end 82end

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

rails 5.1.7

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

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

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

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

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

guest

回答1

0

ベストアンサー

TagList を作るのはTagListsController『だけ』ですか?
明示的に作っていなくても、tag.list に listを代入したり、list.tagにtagを代入するのでも作成されます。
それらがないでしょうか
と言いますのは。TagListsController#create に
@tag_list.user_id = current_user.id
がありますから、ここだけで作っているのなら必ず入ります。
入っていないTagListがあるとすると、ここ以外で作られているものです

なお、中間tableですから

class TagList < ApplicationRecord belongs_to :user, optional: true belongs_to :tag, optional: true belongs_to :list, optional: true end

tag,list の optional: true はまずいです。
user_idも必ず入ってほしいものなら userのoptional: true もまずいです。
これらを外して一通り操作すると、validationでとまるので、上記の場所が判るかも。

追記
よく見ると belongs_to に全部 optional: true が入ってますね。
後で必ず使うものであるなら、これらはまずいです。
で、 List,Tag が属するUserと ListTagが属するUserと3人が出てきますが、これらは全員別人の可能性がある、ということでしょうか?

投稿2019/12/30 00:01

編集2019/12/30 03:03
winterboum

総合スコア23567

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

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

DaikiUTT

2019/12/30 03:02

なるほど、ありがとうございます。 tagとlistのoptional:trueを外して捜査したところ、localhost:3000で実行してTagを作成した後に、Listを作成しようとしたところで、 1 error prohibited this list from being saved: Tag lists is invalid というエラーが出ました。 tag.listやlist.tagは検索したところ存在しなかったのですが、tag_listのhtmlファイルにtag_list.tagやtag_list.listは存在していました。 この場合どこにエラーがあると考えられるでしょうか。勉強不足ですみません。ご指導のほどよろしくお願いします。
winterboum

2019/12/30 03:07

「tag.listやlist.tagは検索したところ存在しなかったのですが」ですが、ドットの左側は単なる変数ですので、Daikiさんのプログラムで、 例えば tag0=Tag.find()とかしてtag0.list などとすればそれも私が懸念しているものです。 viewにあるのは右に = がないと思うので、それは参照するだけですから、懸念しているものとは別物、大丈夫です。 エラーが出たということなので、そのエラーが出たfileを見せてください。 多分それはsaveするところなので、その前に代入している所があるはずなので、そこも判るように。
DaikiUTT

2020/01/02 03:11 編集

listを作成する所でエラーが出たのでlists_controlerを確認したら、一番下のdef list_paramsの部分にtag_ids:[]という記述があって、そこがエラーの原因になっているかもしれません。 エラー文は上記の 1 error prohibited this list from being saved: Tag lists is invalid という文章しか表示されませんでした。 lists_controllerのコードは質問に載せておきます。
winterboum

2019/12/31 01:54

初めに、このcodeコメントから削除して質問本文の方に移動してください。 で 「list_paramsの部分にtag_ids:[]という記述」自身は間違いないですが、 ん〜〜〜 なんか根が深そう。 createみたところここでは TagListを作るような記述になっていないのに、tag_list がinvalidだと言われている。 tag_ids:[] が送られてくるということは、、、、 Listのnewのview、model Listのcodeが必要かも。 コメントに載せないでね。
DaikiUTT

2020/01/02 03:06

返信遅れてすみません。 わかりました。今の自分の技術だと難しそうなので他のアプローチ方法を探して色々やってみます。 質問に答えてくださってありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問