Rails Associations (many to many)

41 Views Asked by At

I'm working with Ruby on Rails ActiveRecord and trying to realize my database structure.

What I want is something link this:

User
id
username
License
id
name
ActiveLicenses
user_id (foreign key to user.id)
license_id (foreign key to license.id)
expiration

And this is how far I've got:

class User < ApplicationRecord
    has_many :active_licenses
    has_many :licenses, :through => :active_licenses

    validates :keycloak_id, presence: true, uniqueness: true
end
class License < ApplicationRecord
    has_many :active_licenses
    has_many :users, :through => :active_licenses

    validates :name, presence: true
end
class ActiveLicense < ApplicationRecord
    belongs_to :users
    belongs_to :licenses

    validates :user_id, presence: true
    validates :license_id, presence: true
end
class AddUsersAndLicenses < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.text "keycloak_id"

      t.timestamps
    end

    create_table :licenses do |t|
      t.text "name"

      t.timestamps
    end

    create_table :active_licenses do |t|
      t.belongs_to :user
      t.belongs_to :license
      t.text "expiration"

      t.timestamps
    end
  end
end

Creating records works just fine with user = User.create(username: "my_username"), License.create(name: "first_license") License.create(name: "second_license"). Now I want to link the user to the licenses: user.licenses = License.all. This failes with the error message: "NameError (uninitialized constant User::Licenses)"

Anyone here who can help me?

2

There are 2 best solutions below

3
Steven Schwartz On

ActiveLicense should have many licenses and licenses should belong_to ActiveLicense.

Try making your model look like this and restart your console / server

class User < ApplicationRecord
    has_many :active_licenses
    has_many :licenses, :through => :active_licenses

    validates :keycloak_id, presence: true, uniqueness: true
end
class License < ApplicationRecord
    belongs_to :active_license


    validates :name, presence: true
end
class ActiveLicense < ApplicationRecord
    belongs_to :user
    has_many :licenses

    validates :user_id, presence: true
    validates :license_id, presence: true
end
0
Andreas On

Yes it was a typo mistake at belongs_to.

This did the trick for me:

class User < ApplicationRecord
    has_many :active_licenses
    has_many :licenses, :through => :active_licenses

    validates :keycloak_id, presence: true, uniqueness: true
end
class License < ApplicationRecord
    has_many :active_licenses
    has_many :users, :through => :active_licenses

    validates :name, presence: true
end
class ActiveLicense < ApplicationRecord
    belongs_to :user
    belongs_to :license

    validates :user_id, presence: true
    validates :license_id, presence: true
end