プログラミングと料理を

プログラミングに疲れたら料理

アソシエーションをeachするとundefined method `each' forとエラーがでる

以下のようなアソシエーションがあります。 f:id:benitobi510:20171010123557p:plain f:id:benitobi510:20171010124358p:plain

MysQlで結果のような出力をするためには以下の内容になります。

SELECT users.* FROM users INNER JOIN facilities ON facilities.id = users.facility_id

ではRailsではどのように書くのでしょうか? まずはModelから

model

class User < ApplicationRecord
  belongs_to :facility
end

class Facility < ApplicationRecord
  has_many :users
end

has_manyがつくのは関連付けのidを持っている方につけます。

この場合usersテーブルが、facility_idをもっているので、 has_manyはFacilityモデルに書くということになります。 また、has_manyに関連するモデルは複数形にしてください。

Controller

@user = User.joins(:facility)

.joinをつけることで、INNERJOINが発生します。 Railsのログを見てみましょう。以下のようなSQLが発行されています。

SELECT `users`.* FROM `users` INNER JOIN `facilities` ON `facilities`.`id` = `users`.`facility_id`

では、Excelの結果の出力をView側で再現してみましょう。

View

- @user.each do |user|
  %tr
    %td= user.facility.email
    %td= user.fa_name

これで結果が出力されました。

さて、エラーが出るのはどのようなときでしょうか? 以下のような場合は、eachしてもエラーがでます。

View

- @user.each do |user|
  - user.facility.each do |fa|
    %tr
      %td= fa.facility.email
      %td= user.fa_name

なぜかというと「facility」が「belongs_to」だからです。 もし、「facility」が「has_many」であればeachをしてもエラーは出力されません。