Railsで多対多のアソシエーションで中間テーブルに外部キー以外のカラムにアクセスする方法

f:id:ihatov08:20160728001100j:plain

Railsで多対多のアソシエーションで中間テーブルに外部キー以外のカラムにアクセスする方法です。


likesテーブルの外部キーは今回の場合user_idproduct_idです。外部キー以外にもlike_typeをもたせています。
このlike_typeカラムですが、0の場合はunlike,1の場合はlikeとして管理したいと思っています。like_typeはenumで管理しています。

今回は各ユーザーがlikeしたproduct一覧を取得しつつ、likesテーブルのlike_typeカラムもviewで表示したいと思います。

rice_curry_table%20(9).pdf

テーブル定義f:id:ihatov08:20160728001100j:plain

  create_table "likes", force: :cascade do |t|
t.integer  "product_id", limit: 4, null: false
t.integer  "user_id",    limit: 4, null: false
t.integer  "like_type",  limit: 4, null: false
t.datetime "created_at",           null: false
t.datetime "updated_at",           null: false
end
create_table "users", force: :cascade do |t|
t.string   "name",                     limit: 255,               null: false
t.string   "email",                    limit: 255,               null: false
t.datetime "created_at",                                         null: false
t.datetime "updated_at",                                         null: false
end
create_table "products", force: :cascade do |t|
t.string   "name",                limit: 255,   null: false
t.text     "description",         limit: 65535, null: false
t.datetime "created_at",                        null: false
t.datetime "updated_at",                        null: false
end

アソシエーション

class User < ActiveRecord::Base
has_many :likes
has_many :like_products, through: :likes, source: :product
end
class Product < ActiveRecord::Base
has_many  :likes
has_many :like_users, through: :likes, source: :user
end
class Like < ActiveRecord::Base
belongs_to :product
belongs_to :user
enum like_type: [ :dislike, :like]
end

ルーティング

今回はユーザーがlikeしたproduct一覧を表示するので以下のようなルーティングを設定しています。

  resources :users do
member do
get 'likes'
end
end

controller

  def likes
@user = User.find(params[:id])
@products = @user.like_products
end

viewでアクセスする方法

each文をネストしています。子ネストでproduct.likesだけにすると親ネストで取得したproductsのidを持つlikesテーブルのレコードをすべて取得してきてしまいます。
そのためwhereで取得してきたいuserを絞り込んでいます。

<% @products.each do |product| %>
<% product.likes.where(user_id: @user.id).each do |like| %>
<%= product.name %>
<%= like.like_type %>
<% end %>
<% end %>

もっときれいに書きたい

each文をネストしているし、もっとうまく、きれいに書きたいです。他に良い方法をご存知の方がいらっしゃいましたら教えてください!

改訂3版 基礎 Ruby on Rails 基礎シリーズ

改訂3版 基礎 Ruby on Rails 基礎シリーズ

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です