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

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

ただいまの
回答率

89.12%

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

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 185

DaikiUTT

score 5

前提・実現したいこと

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を代入できるようにすることです。

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

create_table "tags", force: :cascade do |t|
  t.string "content"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.integer "user_id"
end

create_table "lists", force: :cascade do |t|
  t.string "content"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.integer "user_id"
  t.date "start_time"
end

create_table "tag_lists", force: :cascade do |t|
  t.integer "tag_id"
  t.integer "list_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.integer "user_id"
  t.index ["list_id"], name: "index_tag_lists_on_list_id"
  t.index ["tag_id"], name: "index_tag_lists_on_tag_id"
end

create_table "users", force: :cascade do |t|
  t.string "email", default: "", null: false
  t.string "encrypted_password", default: "", null: false
  t.string "reset_password_token"
  t.datetime "reset_password_sent_at"
  t.datetime "remember_created_at"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.index ["email"], name: "index_users_on_email", unique: true
  t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end

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

class Tag < ApplicationRecord
  belongs_to :user, optional: true
  has_many :tag_lists, dependent: :destroy
  has_many :lists, :through => :tag_lists
end

class List < ApplicationRecord
  belongs_to :user, optional: true
  has_many :tag_lists, dependent: :destroy
  has_many :tags, :through => :tag_lists
end

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

class User < ApplicationRecord
  has_many :diaries
  has_many :tags
  has_many :lists
  has_many :tag_lists
end

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

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

該当のソースコード

class TagListsController < ApplicationController
  before_action :set_tag_list, only: [:show, :edit, :update, :destroy]

  def index
    @tag_lists = TagList.where(user_id: current_user.id)
  end

  # GET /tag_lists/1
  # GET /tag_lists/1.json
  def show
  end

  # GET /tag_lists/new
  def new
    @tag_list = TagList.new
  end

  # GET /tag_lists/1/edit
  def edit
  end

  # POST /tag_lists
  # POST /tag_lists.json
  def create
    @tag_list = TagList.new(tag_list_params)

    @tag_list.user_id = current_user.id
    #@tag_list.user_id = tag_list.list.user_id

    respond_to do |format|
      if @tag_list.save
        format.html { redirect_to @tag_list, notice: 'Tag list was successfully created.' }
        format.json { render :show, status: :created, location: @tag_list }
      else
        format.html { render :new }
        format.json { render json: @tag_list.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /tag_lists/1
  # PATCH/PUT /tag_lists/1.json
  def update
    respond_to do |format|
      if @tag_list.update(tag_list_params)
        format.html { redirect_to @tag_list, notice: 'Tag list was successfully updated.' }
        format.json { render :show, status: :ok, location: @tag_list }
      else
        format.html { render :edit }
        format.json { render json: @tag_list.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /tag_lists/1
  # DELETE /tag_lists/1.json
  def destroy
    @tag_list.destroy
    respond_to do |format|
      format.html { redirect_to tag_lists_url, notice: 'Tag list was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_tag_list
      @tag_list = TagList.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def tag_list_params
      params.require(:tag_list).permit(:tag_id, :list_id)
    end
end
class ListsController < ApplicationController
before_action :set_list, only: [:show, :edit, :update, :destroy]

# GET /lists
# GET /lists.json
def index

#@list = List.find(params[:id])

@lists= List.where(user_id: current_user.id).order("start_time ASC")
end

# GET /lists/1
# GET /lists/1.json
def show
end

# GET /lists/new
def new
@list = List.new
end

# GET /lists/1/edit
def edit
end

# POST /lists
# POST /lists.json
def create
@list = List.new(list_params)

@list.user_id = current_user.id

#@list.tag_list.user_id = current_user.id


respond_to do |format|
if @list.save
format.html { redirect_to @list, notice: 'List was successfully created.' }
format.json { render :show, status: :created, location: @list }
else
format.html { render :new }
format.json { render json: @list.errors, status: :unprocessable_entity }
end
end
end

# PATCH/PUT /lists/1
# PATCH/PUT /lists/1.json
def update
respond_to do |format|
if @list.update(list_params)
format.html { redirect_to @list, notice: 'List was successfully updated.' }
format.json { render :show, status: :ok, location: @list }
else
format.html { render :edit }
format.json { render json: @list.errors, status: :unprocessable_entity }
end
end
end

# DELETE /lists/1
# DELETE /lists/1.json
def destroy
@list.destroy
respond_to do |format|
format.html { redirect_to tag_lists_url, notice: 'List was successfully destroyed.' }
format.json { head :no_content }
end
end

private
# Use callbacks to share common setup or constraints between actions.
def set_list
@list = List.find(params[:id])
end

# Never trust parameters from the scary internet, only allow the white list through.
def list_params
params.require(:list).permit(:content,:start_time, tag_ids:[])
end
end

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

rails 5.1.7

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

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/31 01:19 編集

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

    lists_controllerのコードは質問に載せておきます。

    キャンセル

  • 2019/12/31 10:54

    初めに、このcodeコメントから削除して質問本文の方に移動してください。

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

    キャンセル

  • 2020/01/02 12:06

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

    キャンセル

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

  • ただいまの回答率 89.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る