programmer321 programmer321 - 1 year ago 33
Ruby Question

Is it possible to store an attribute on a model, but is only accessible through the association?

I'm building an ecommerce platform and was looking over the database design.

These are the models in my ecommerce site:

class User < ApplicationRecord
belongs_to :cart, {:optional => true}
end


class Cart < ApplicationRecord
has_and_belongs_to_many :phones
has_one :user
end

class Phone < ApplicationRecord
has_and_belongs_to_many :carts # has join table with Cart
has_and_belongs_to_many :orders
end


class Order < ApplicationRecord
belongs_to :user, {:optional => true}
has_and_belongs_to_many :phones #HAS join table with Phone
end


My site is selling phones (
Model Phone
) to users (
Model User
), who put them in carts (
Model Cart
), and once the order gets submitted, an order gets created (
Model Order
).

I want to update the quantities sold by putting
@user.cart.phones
(
@user
= current user) into the Order model, after the purchase has been submitted and finalized. The trouble I'm having is how I should design the database schema in so that I can track the type of phone being sold, and how many of that particular phone were sold in the order.

I was thinking something along the lines of
@user.order.phones
, and have an attribute called quantity on the
Phone
model. The problem with that is that the Phone model would be accessible to all users, hence, it would overwritten the moment another user submitted their order.

My question is, is it possible to have an attribute on the Phone model, only accessible to
@user.cart
(i.e.:
@user.cart.phones.phones_sold
-->
.phones_sold
would only be available through
@user.cart
and would be unique for each user)? If not, how could I go about designing my Model/Database to include an order model that has information about each order (type of phone, and quantity sold) that's unique to each individual user?

Answer Source

you have

class Cart < ApplicationRecord
  has_and_belongs_to_many :phones
end

 class Phone < ApplicationRecord
   has_and_belongs_to_many :carts # has join table with Cart
 end

and this is a good start, but the trouble is the join table is not directly accessible to your application.

Do instead...

class Cart < ApplicationRecord
  has_many :cart_phone_links
  has_many :phones, through: :cart_phone_links
end

 class Phone < ApplicationRecord
  has_many :cart_phone_links
  has_many :carts, through: :cart_phone_links
 end

class CartPhoneLink < ApplicationRecord
  belongs_to :cart
  belongs_to :phone
end

This gives you the same functionality as has_and_belongs_to_many but because the new table is actually a table accessible by rails you can add other fields ot it that give more information about the relationship, such as quantity

This is generally why has_many ... through: is considered more flexible than has_and_belongs_to_many

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download