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

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

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

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

Devise

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Ruby

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

Ruby on Rails

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

Active Record

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

Q&A

解決済

3回答

1850閲覧

(Rails)多対多で関連付けられているモデルを取得できない

widget11

総合スコア221

Ruby on Rails 5

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

Devise

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Ruby

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

Ruby on Rails

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

Active Record

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

0グッド

0クリップ

投稿2019/03/24 15:55

編集2019/03/24 15:59

質問文通りですが多対多で関連付けられているモデルが取得できません。
ER図で書くと以下のようなリレーションになっております。
なお、ユーザーモデルはdevise製のものです。

イメージ説明

一つのユーザーは応募テーブルを介して多数の仕事を持っており、
仕事テーブルは応募テーブルを介して多数のユーザーをもっているという作りになっています。

ActiveRecordのリレーションは以下のように書いています。

#TWorkモデル class TWork < ApplicationRecord has_many :user_accounts, through: :t_applicants, source: :t_user end #TUserモデル class TUserAccount < ApplicationRecord has_many :t_works, through: :t_favorite, source: :t_work devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :confirmable #TApplicantモデル class TApplicant < ApplicationRecord belongs_to :t_work belongs_to :t_user end

以上の条件を踏まえて現在ログインしているユーザーが応募している 仕事の値(例では仕事のタイトル)を取ってきたいのですが、メソッドの書き方が悪いのか、リレーションメソッドの書き方がおかしいのか取得できません。取得しているメソッドは以下のようにしています。

#userモデル class TUserAccount < ApplicationRecord has_many :t_works, through: :t_favorite, source: :t_work devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :confirmable def show_work(user_id) #ここのメソッドの中身をどう書けばいいかわからない TUser.includes(:t_works).where(t_user: {id: user_id}) end end #userコントローラー/TUserモデルをインスタンス化し、show_workメソッドを呼び、引数に現在のユーザーのidを渡す class TUserController < ApplicationController def show worklist = TUser.new @worklist = worklist.show_work(params[:id])  #もしくは  @worklist = worklist.show_work(current_t_user.id) end end <!-- show.html.erb --> <h1>応募中仕事一覧</h1> <% @worklist.each do |work| %> <%= work.title %> <% end %>

こうすると@worklistはnilclassやら、少しいじるとミススペルじゃないか?等エラーを吐きます。

コメントにも書いておりますが、分からないことはdef show_workメソッドの中身の書き方と、またモデルクラスのhas_many_thoroughメソッドのオプション等の書き方です。
この3つのテーブルを全て結合し、候補者テーブルの外部キーt_user_idが現在ログインしているユーザーとマッチした仕事テーブルの値を取るということをしたいのですがどうすればよいでしょうか?
色々調べて試したのですが3日間くらい詰まっています。

長くなり申し訳ございませんが、よろしくお願い致します。

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

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

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

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

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

guest

回答3

0

TUserモデル

ruby

1class TUserAccount < ApplicationRecord 2 has_many :t_applicants 3 has_many :t_works, through: :t_applicants, source: :t_work 4 devise :database_authenticatable, :registerable, 5 :recoverable, :rememberable, :validatable, :confirmable 6end

候補者テーブルの外部キーt_user_idが現在ログインしているユーザーとマッチした仕事テーブルの値を取る

作成したアソシエーションを使いましょう。

class TUserController < ApplicationController def show # ログインしているユーザーを仮にcurrent_userとする @worklist = current_user.t_works end end

投稿2019/03/24 18:48

編集2019/03/24 18:49
ykp_yk

総合スコア654

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

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

0

ベストアンサー

def show_work(user_id) #ここのメソッドの中身をどう書けばいいかわからない TUser.includes(:t_works).where(t_user: {id: user_id}) end

このメソッドに関しては、まずTUserがt_worksのような子テーブルを持っている訳ではないのでinvalidになっているのだと思います。

なので、t_users_controller.rbのshowアクションの中で、

@worklist = T_applicant.includes(:t_work).where(t_user_id: @t_user.id)

などとして見るのが良いのかなと思います。本来、includeをメソッドを利用する目的としては、アソシエーションを用いてt_applicants.userなどとするとN+1問題が発生してしまうので、そのための対策としてincludeメソッドで先にt_worksの情報を取得する...といった手順をとります。

投稿2019/03/24 17:40

bamboo-nova

総合スコア1408

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

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

widget11

2019/03/24 18:43

無事解決できました! ありがとうございます!
guest

0

まず、モデルの部分のTWorkに関して、

class TWork < ApplicationRecord has_many :user_accounts, through: :t_applicants, source: :t_user end

この部分ですが、t_worksからみている中間テーブルとの関係を記述していないことが問題だと思われます。参照している中間テーブルがないのが一つ目の問題です。

ですので、以下のように変更するべきだと思います。

class TWork < ApplicationRecord has_many :t_applicants has_many :user_accounts, through: :t_applicants, source: :t_user end

また、TUserモデルに関しても中間テーブルを参照しておらず、中間テーブルの名前も誤りがあります。

#TUserモデル class TUserAccount < ApplicationRecord has_many :t_works, through: :t_favorite, source: :t_work devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :confirmable

なので、こちらもhas_many :t_applicantsが必要です。

多対多の関係は、あくまで二つの一対多の関係の関係ですので、そちらに気をつけてコーディングしていくと良いのではないかと思います。

投稿2019/03/24 16:25

bamboo-nova

総合スコア1408

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

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

widget11

2019/03/24 17:16

ご回答ありがとうございます! リレーションメソッドの書き方を知らずthroughオプションをつければよいと考えていました。 ちなみになのですが、、、show_workメソッドの中身はどのようにすればいいでしょうか。。。 やりたいことは  >候補者テーブルの外部キーt_user_idが現在ログインしているユーザーとマッチした仕事テーブルの値を取る ということなのですが、、、 言われたとおり再度リレーションメソッドを書き加え、しっかりとした名前の指定を行い def show_work(user_id) TWork.includes(:t_applicants).where(t_performer_account_id: user_id) end としてみたのですが値が入ってきていないのかstatement invalidが出てきてしまい。。。 よろしくお願い致します
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問