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

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

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

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

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

Q&A

解決済

1回答

2112閲覧

【rails】【DB】中間テーブル

gogoackman3

総合スコア109

Ruby on Rails

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

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

0グッド

1クリップ

投稿2016/10/26 09:44

編集2016/10/27 09:09

###やりたいこと

・ユーザーが好きなゲームをフォロー出来る。
・ユーザーはゲームをフォローする際、自身のゲームレベルをゲーム毎に登録しておける。
・ゲームはユーザーをフォロー出来ない。(しない)

###ここまでは出来た

・ユーザーがゲームをフォローする
・中間テーブルに該当レコードをINSERT

###ここが出来ない

・ユーザーがゲームをフォローした際に、中間テーブルでレコード生成し(ここまでならOK)、そのゲーム毎に自身のゲームレベルを中間テーブルの該当レコードのrankカラムに登録しておく

###やった事

中間テーブルを作成

ruby

1class CreateFollowGames < ActiveRecord::Migration[5.0] 2 def change 3 create_table :follow_games do |t| 4 t.boolean :active, null: false, default: true 5 t.references :user, foreign_key: true 6 t.references :game, foreign_key: true 7 t.integer :rank 8 9 t.timestamps 10 end 11 end 12end

モデルの関連付け

▼user.rb

ruby

1has_many :follow_games 2has_many :following_games, through: :follow_games, source: :game

▼game.rb

ruby

1関連付けなし

▼follow_game.rb

ruby

1class FollowGame < ApplicationRecord 2 belongs_to :user 3 belongs_to :game 4end

viewのフォーム作成

ruby

1= form_for(current_user.follow_games.build) do |f| 2 = f.text_field :rank, id:'rank', placeholder: "#{game.rank_name}を入力" 3 = f.hidden_field :game_id, value:"#{game.id}" 4 = f.submit '追加', id:"rank_set"

controller作成

ruby

1class FollowGamesController < ApplicationController 2 3 before_action :set_game 4 5 def create 6 current_user.following_games << @game unless current_user.following_games.exists?(@game.id) 7 end 8 9 private 10 def set_game 11 @game = Game.find(params[:follow_game][:game_id]) 12 @game_rank = params[:follow_game][:rank] 13 end 14end

###発生するエラー

やった事のコードを実行すると以下のエラーにご対面・・・。

イメージ説明

###教えて欲しい事

どうすれば、ゲームをフォローすると同時に中間テーブルのrankカラムにrank情報を追加出来るのか。

もしかして、rankテーブルを別途用意するようなアプローチじゃないと難しいでしょうか??

何とぞよろしくお願い致します・・・!

###質問に関する追記

camelubyさんの質問への追記情報

①この他にbefore_action等ありますか?
→特にありません!

②Gameにrankをセットしていろところは無いようなので。

→rankは中間テーブルにつけていて、Gameテーブルにはありません。
また、postで投げたrank情報は受け取ってはいるものの、前述のcreateのコードでどう使えばいいのか分からず・・・使えていません。。。

以下、Gameのテーブル情報です。

ruby

1class CreateGames < ActiveRecord::Migration[5.0] 2 def change 3 create_table :games do |t| 4 t.boolean :active, null: false, default: true 5 t.string :title, null: false, default: '' 6 t.string :icon, null: false, default: '' 7 t.string :level_name, null: false, default: '' 8 t.string :search_tag, null: false, default: '' 9 t.integer :feed_range, null: false, default: 0 10 t.integer :follower_num, null: false, default: 0 11 12 t.timestamps 13 end 14 end 15end

最後に、自分なりに見直して以下のようなコードなら動くようにはなりました。

ruby

1class FollowGamesController < ApplicationController 2 3 before_action :set_game 4 5 def create 6 current_user.follow_games.create(game_id: @game, rank: @game_rank) 7 end 8 9 private 10 def set_game 11 @user = params[:follow_game][:user_id] 12 @game = params[:follow_game][:game_id] 13 @game_rank = params[:follow_game][:rank] 14 end 15end

もともと載せていた以下のcreateのコードを利用する形でも前述の《ここが出来ない》の部分のことが実現出来るのでしょうか??

ruby

1class FollowGamesController < ApplicationController 2 3 before_action :set_game 4 5 def create 6 current_user.following_games << @game unless current_user.following_games.exists?(@game.id) 7 end 8 9 private 10 def set_game 11 @game = Game.find(params[:follow_game][:game_id]) 12 @game_rank = params[:follow_game][:rank] 13 end 14end

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

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

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

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

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

cameluby

2016/10/26 12:52 編集

この他にbefore_action等ありますか?できるだけ多くのコードをお願いします。載せてもらっているコードを見る限りはGameにrankをセットしていろところは無いようなので。
gogoackman3

2016/10/27 09:10

ありがとうございます。こちら質問本体に追加情報を書かせていただいたので、確認頂けると嬉しいです!
guest

回答1

0

ベストアンサー

追記も含めて見たところ、質問者さんの実現したいことはシンプルに以下のコードで出来るような気がします。

ruby

1class FollowGamesController < ApplicationController 2 def create 3 current_user.follow_games.create(folow_game_params) unless current_user.following_games.exists?(params[:follow_game][:game_id]) 4 end 5 6 private 7 def follow_game_params 8 params.require(:follow_game).permit(:game_id, :rank) 9 end 10end

投稿2016/10/28 00:43

cameluby

総合スコア891

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

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

gogoackman3

2016/10/28 02:04

ありがとうございます! あーそうでした、postで受け取った値は一旦指定の値だけに許可を与えないといけないんでしたね。。。 お陰様でこちらで問題なく実装できました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問