Search code examples
ruby-on-railsmany-to-manyassociations

Rails many-to-many through relationship returning empty array


I'm a beginner in rails and am making a card app. I have a user, card, and user_card models with a many to many, through relationship set up between the cards and users. My problem is that when I return the card table and try to include: the users I get an empty array. I've tried resetting the database but still nothing.

ActiveRecord::Schema.define(version: 2022_06_15_200100) do

  create_table "cards", force: :cascade do |t|
    t.string "name"
    t.string "image"
    t.string "text"
    t.integer "level"
    t.string "types"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.integer "quantity", default: 0
  end

  create_table "user_cards", force: :cascade do |t|
    t.integer "user_id"
    t.integer "card_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["card_id"], name: "index_user_cards_on_card_id"
    t.index ["user_id"], name: "index_user_cards_on_user_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "username"
    t.string "password_digest"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end
class User < ApplicationRecord
   has_secure_password
   has_many :user_cards 
   has_many :cards, through: :user_cards
  
end

class Card < ApplicationRecord
    has_many :user_cards

    has_many :users, through: :user_cards


end

class UserCard < ApplicationRecord
    belongs_to :user
    belongs_to :card
end

controller

class CardsController < ApplicationController

    wrap_parameters false
    
    def create 
        card = Card.create(card_params)
       if card.valid?
        render json: card, status: :created, include: :users
        else 
        render json:{errors: card.errors}
    end


    def index
      card = Card.all 
      render json: card, include: :users
        
    end
    

Solution

  • In order for the User.first.cards to work, you need to ensure the application is inserting data in the user_cards table. You may check if there are any records in there by doing UserCard.all in your rails console.

    Coming to the controller, after creating a card record, you have to assign it to a user record in order for the relationship to be established.

    def create 
       card = Card.create(card_params)
       if card.valid?
        card.users << current_user # Or card.users << (any user object like) User.first
        render json: card, status: :created, include: :users
       else 
        render json:{errors: card.errors}
       end
    end
    

    card.users << user object will create the necessary record in the user_cards table and you'll be able to access them using includes: :user

    You may refer the examples given - here in the Rails API guide