8
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Railsで中間テーブルの外部キー以外に持たせたカラムにviewでアクセスする方法

Posted at

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

テーブル定義

schema.rb
  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

アソシエーション

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

ルーティング

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

routes.rb
  resources :users do
    member do
      get 'likes'
    end
  end

controller

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

viewでアクセスする方法

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

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

もっときれいに書きたい

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

8
14
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?