jpittis
jpittis

Reputation: 177

rails many to many and one to many ownership

I have two models Item and User. An Item is created and owned by a User. But an Item also has users other than its owner.

It seems like I need a many to many relationship between items and users. But in addition, I also need a one to many ownership relation of a user who owns many items.

class User < ActiveRecord::Base
  has_many :items, dependent: :destroy
  has_and_belongs_to_many :items
end

class Item < ActiveRecord::Base
  belongs_to :user
  has_and_belongs_to_many :users
end

I've set up my migrations like so.

A table to hold the many connections between users and items.

create_table :items_users, :id => false do |t|
  t.column :item_id, :integer
  t.column :user_id, :integer
end

As well as the ownership of an Item by a User.

add_reference :items, :user, index: true
add_foreign_key :items, :users

This means I can access the owner of an Item with item.user_id. I can also access the many to many relationship of users and items with item.users and user.items.

I do not know how to access the items that a User owns through a User object. The items that a User owns should be different from the ones in the many to many relationship of user.items.

I feel like I'm structuring everything wrong. I'm extremely new to rails and I'm quite confused. What is the proper way to accomplish this in rails?

Upvotes: 1

Views: 475

Answers (2)

ilan berci
ilan berci

Reputation: 3881

class User < ActiveRecord::Base
  has_many :user_items, dependent: :destroy 
  has_many :items, through: :user_items

  has_many :owned_items, through: :user_items, source: item, where: -> {
    user_items: {owned: true}
  }
end

class Item < ActiveRecord::Base
  has_many :user_items, dependent: :destroy
  has_many :users, through: :user_items
end

class UserItem < ActiveRecord::Base
  belongs_to :user
  belongs_to :item

  scope :owned, -> {
    where(owned: true)
  }
end

create_table :user_items |t|
  t.references :user
  t.references :item
  t.boolean :owned, null: false, default: false
end

Upvotes: 2

Ido Traini
Ido Traini

Reputation: 83

I'm sure that with a many-to-many association from User and Item you can resolve, but if you want a clearer solution you have to "traslate" your idea in the data model (oob way).

You tell us: Item have an owner, that is an user, and have many users. So you need an Owner model and build a has_one :throught association

For example, for Item model you can set:

>has_many :users 
>has_one :user throught :owners
>has_one :owner

For User model you can set:

>has_many :items
>belongs_to :owner

For Owner model you can set:

>has_one :user
>belongs_to :item

Upvotes: 0

Related Questions