When should my model belong to another one? - ruby-on-rails

I'm unsure if I can accomplish what I want with my associations.
This is the scenario I want in my application:
A user will select a Store. Then inside of that Store a user selects a product and then can add a new price to that product.
class Business < ActiveRecord::Base
has_many :stores
end
class Store < ActiveRecord::Base
belongs_to :business
has_many :prices
end
class User < ActiveRecord::Base
has_many :prices, :dependent => :destroy
has_many :products, :through => :prices
end
class Price < ActiveRecord::Base
belongs_to :user
belongs_to :product
belongs_to :store
end
class Product < ActiveRecord::Base
has_many :prices
has_many :users, :through => :prices
end
I'm not sure if this is correct since products don't belong to a store (integer store_id in table).
What do I need to do to make this scenario work out? Is this the right design?

This is a good and correct design for what you are trying to do.
If a product belonged to a store, then a product could only be at one store. Since store may have many products and products may be sold at many stores, you need another table referencing both the product and store.

Related

Model for an eCommerce shop

I'm trying to create an eCommerce shop. My main idea is every user can create their own store, and I have models like this:
model/user.rb:
class User < ApplicationRecord
has_one :store
end
model/store.rb:
class Store < ApplicationRecord
belongs_to :user
has_many :products
end
model/product.rb
class Product < ApplicationRecord
belongs_to :store
end
I don't know if the relationships between these models is good enough or I should modify them. And for further update, if user_1 add product sold by user_2 to his cart, I don't know what will the relationship be between these two users
Your models don't have a relationship between User and Product yet.
You can say User has_many: :products
and Product has_one: :user but this relationship would be incomplete.
The user-product relationship needs to be done through the store. That's where has_many: through comes in handy.
User has_many :products, through: :store
Product has_one :user, through: :store

Rails model has and belongs to many list types

I have two models, User and Product
class User < ActiveRecord::Base
has_and_belongs_to_many :products
end
class Product < ActiveRecord::Base
has_and_belongs_to_many :users
end
Now I want to make three lists for each user, products they've checked out recently, products that are in their shopping cart and products which they have bought. How do I make a distinction between these relations? Could I add some sort of type column to the relation table? And how could I then later check this type?
Thanks
If you and to add other columns to the relation table perhaps you should consider using has_many on both User and Products, then you can add your columns on Cart
class User < ActiveRecord::Base
has_many :carts
has_many :products, through: :carts
end
class Cart < ActiveRecord::Base
belongs_to :user
belongs_to :product
end
class Product < ActiveRecord::Base
has_many :carts
has_many :users, through: :carts
end

What is the right way to set up a many to many association in Rails

So I've got three models in my app, a User, Review and a Movie model. A user can review many movies (one per movie), a Movie can have many reviews from many users. Their connection is a review.
Am I doing the following setup right?
class Movie < ActiveRecord::Base
has_many :reviews, :through => :users
end
class Review < ActiveRecord::Base
belongs_to :user
belongs_to :project
end
class User < ActiveRecord::Base
has_many :reviews, :through => :movies
end
I'm hoping I can do something like:
User.reviews (which would give me back the user's reviews and the corresponding id of the movie which the review relates to)
Thanks
I believe this is the approach you should be taking
class User < ActiveRecord::Base
has_many :reviews
has_many :movies, :through => :reviews
end
class Review < ActiveRecord::Base
belongs_to :user
belongs_to :movie
end
class Movie < ActiveRecord::Base
has_many :reviews
has_many :users, :through => :reviews
end
You would also want to validate uniqueness in the model Review and/or enforce uniqueness on the join-table to only allow a single user per movie. It's up to you if you want to take this UQ constraint into the schema as well (DHH says 'Yes', I say 'the slathering of dumb persistance' is a 'No no'...)
User.reviews will give you the 'join records', i.e. along the lines of <Review user_id=x, movie_id=y> Certainly, you'd have a lot more columns on the join table pertaining to the review, such as :summary, :content etc. It's easy enough to access the movie from a review, i.e. Movie.find_by_id(User.reviews.last.movie_id).title

One to many relationships in Rails

I'm having a hard time setting up the basic structure of my databases.
I have products (about 50). Each products is related to one or more place(s).
The basic schema would be this (no relation yet)
Products
id:integer
name:string
Places
id:integer
name:string
content:string
I first tought I could connect places and products by adding place_id to products and has_many belong_to in the controllers, but since a product can have more than one place, I don't know how.
If a Product has_many Places and a Place has_many Products your association needs to be many-to-many.
There are two ways to do this in Rails, the most recommended is a join model. You explicitly label the relationship between Products and Places. You could call it ProductLocation or Shop or similar, it would look like this:
product_locations:
product_id
place_id
class ProductLocation < ActiveRecord::Base
belongs_to :product
belongs_to :place
end
class Place < ActiveRecord::Base
has_many :product_locations
has_many :products, :through => :product_locations
end
class Product < ActiveRecord::Base
has_many :product_locations
has_many :places, :through => :product_locations
end
See http://guides.rubyonrails.org/association_basics.html#choosing-between-has_many-through-and-has_and_belongs_to_many
Just use through connection
ProductsPlaces (new table)
product_id
place_id
And in models
class Product < ActiveRecord::Base
has_many :places, :through => :products_places
end
class Place < ActiveRecord::Base
has_many :products, :through => :products_places
end
Also there is has_and_belongs_to_many which do in fact the same (with ProductsPlaces table)
class Product < ActiveRecord::Base
has_and_belongs_to_many :places
end
class Place < ActiveRecord::Base
has_and_belongs_to_many :products
end
But better use through, because has_and_belongs_to_many will be deprecated.
It sounds like you want to add product_id to places.
Product has_many Places
Place belongs_to Product

Active record: Querying nested many to many models

I have a Store that has many Catalogs and in turn each catalog has many Products.
The Product and Catalog shares many to many relationship.
One product can belong to many catalogs and vice-verse.
So, my model definition goes like this:
class Store < ActiveRecord::Base
has_many :store_catalogs
has_many :catalogs, :through => :store_catalogs
end
class StoreCatalog < ActiveRecord::Base
belongs_to :store
belongs_to :catalog
end
class Catalog < ActiveRecord::Base
has_many :store_catalogs
has_many :stores, :through => :store_catalogs
has_and_belongs_to_many :product_set, :class_name => "Product"
end
class Product < ActiveRecord::Base
has_and_belongs_to_many :catalogs
end
Now, I would like to access all the products that belongs to a store.
How do I link those together so that I get that? please suggest.
I am trying out various combinations from the rails console to pull the data, not sure if the console itself limits the relation based querying by any chance(though i would like to believe it doesn't).
I think this should solve your problem
class Store < ActiveRecord::Base
has_many :catalogs
has_many :products, :through => :catalogs
end
class Catalog < ActiveRecord::Base
belongs_to :store
has_and_belongs_to_many :products
end
class Product < ActiveRecord::Base
has_and_belongs_to_many :catalogs
end
And then you just need a table in your database called catalogs_products with catalog_id and product_id to link the has_and_belongs_to_many association.
Then in order to get all the products from a store just do
Store.find(id).products

Resources