In my rails 3 model, I have two classes: Product, Service. I want both to be of type InventoryItem because I have another model called Store and Store has_many :InventoryItems
This is what I'm trying to get to, but I'm not sure how to model this in my InventoryItem model and my Product and Service models. Should InventoryItem just be a parent class that Product and Service inherit from, or should InventoryItem be modeled as a class abstract of which Product and Service extend from.
Thanks in advance for the advice!
Personally, I would not use inheritance. Why don't you just say
has_many :services
has_many :products
Inheritance is pretty expensive - both in terms of runtime and often in readability too. This case sounds like a very basic case for which no inheritance is required. Do you really want products and services to actually INHERIT something from a base class? What you writes indicates all you want is to establish the association.
I'd use neither, and follow what Mörre suggested to have InventoryItem be a join model:
class Store
has_many :inventory_items
has_many :products, :services, :through => :inventory_items
end
class InventoryItem
belongs_to :store
belongs_to :products, :services
end
class Product
has_many :inventory_items
has_many :stores, :through => :inventory_items
end
class Service
has_many :inventory_items
has_many :stores, :through => :inventory_items
end
Related
class Category
has_many :services
end
class Service
belongs_to :category
belongs_to :order
end
class Order
has_many :services
end
How to organize a connection, where I can refer to orders from an object of the category,
It is natural that orders are specifically in this category for services that are
they have.
For example:
category = Category.first
category.orders
Use has_many :through.
class Category
has_many :services
has_many :orders, through: :services
end
I recommend you take a look at the Rails association basics guide.
I am trying to set up the model structure that has a User model Project model along with two join tables setup as has_many through to manage two specific aspects of the Project, ProjectManagers and ProjectMembers.
I can setup two has_and_belongs_to_many but it doesn't feel very railsy.
Right now, this is what I have and I'm unsure of how to proceed to use multiple has_many through (Project Manager, Project Member) both referencing User model.
Would a nested through be the way to go even if a Project Manager will not always be part of the Project User table?
project.rb
class Project < ApplicationRecord
has_many :project_members
has_many :users, through: :project_manager
end
user.rb
class User < ApplicationRecord
has_many :project_managers
has_many :users, through: :project_managers
end
project_manager.rb
class ProjectManager < ApplicationRecord
belongs_to :project
belongs_to :user
end
project_member.rb
class ProjectMember < ApplicationRecord
belongs_to :project
belongs_to :user
end
I don't see any problems with what you're doing. There are other options, but this approach should work as you want. Have you tried it? I'd do something like this.
class Project < ApplicationRecord
has_many :project_members
has_many :project_managers
has_many :members, through: :project_members, :class_name => User.to_s
has_many :managers, through: :project_manager, :class_name => User.to_s
end
Another approach, since the join tables are similar is to subclass them and add a type column to the join table. Not necessarily better than what you're doing.
You could also create a project_users table (don't separate members and managers) and include a "role" column. A scope on project_user.rb would bring back managers or members.
Personally, I would go with your approach. Managers will likely have different auth and have relationships with other objects. It's simpler to query and less likely to make a mistake.
And, I wouldn't recommend a has_and_belongs_to_many, you're likely to add other columns to the join table and you'll be glad you have the model.
i'm building a RoR app
this is my original scenario:
2 models, Clienti and Interventi
class Clienti < ActiveRecord::Base
has_many :interventi, :dependent => :destroy, :foreign_key => "cliente_id"
......
end
class Interventi < ActiveRecord::Base
belongs_to :clienti, :foreign_key => "cliente_id"
.........
end
this is a simple one-to-many relation, each "clienti" has many "interventis" (iterventi is a kind of job in my app).
Today i need to convert this relation from one-to-many to many-to-many, each "interventi" need to have more then one "clienti", so i think i have to change the "cliente_id" column in DB from int to text and store an array of "Clienti's ids" (is it the good way? )
My question is: if it's the good way, how can i keep the association in model so i can still use something like "Clienti.Interventi.count" ?
Thanks to all!
You would need a join model to do this kind of many-to-many association. By convention, you could call it clienti_interventi
class Clienti
has_many :clienti_interventis
has_many :interventis, through: :clienti_interventis
end
class Interventi
has_many :clienti_interventis
has_many :clientis, through: :clienti_interventis
end
class ClientiInterventi
belongs_to :clienti
belongs_to :interventi
end
With this setup, you can keep doing whatever you were doing, as well as Clienti.first.interventis.count or Interventi.first.clientis.count
I'm looking to create a simple relationship model with the following:
I have 2 main items. Product / WishList
The relationship between them is pretty straight forward a WishList has_many :products and a Product belongs_to_many :wishlists
I understand that there isn't a belongs_to_many association and as simple as this may be I can't seem to wrap my head around the right relationship model.
If someone could suggest a nice way to achieve this it would be much appreciated.
Thanks.
You have a choice between a has_many :through and a has_and_belong_to_many relation.
Pick the first one if you need to attach other attributes to the model that will be the bridge (for instance a position, if you want to order your wishlist), or the second one otherwise (more about that here)
So it could look like so
class Product < ActiveRecord::Base
has_many :items
has_many :wishlists, through: :items
end
class Item < ActiveRecord::Base
belongs_to :product
belongs_to :wishlist
end
class Wishlist < ActiveRecord::Base
has_many :items
has_many :products, through: :items
end
So I'm Rails n00b and I want to create a "favorites" relationship such that a User can have many favorite Item. I'm not entirely sure how to do this, this is how I'm going to try but I'm not sure if this is a good practice at all:
class User < ActiveRecord::Base
has_many :favorites
//other code
end
class Favorite < ActiveRecord::Base
belong_to :user
has_one :item
end
class Item < ActiveRecord::Base
belongs_to :item
end
Is this a good way to do it? Should I be using has_and_belongs_to_many ?
I'm specially concerned in the following scenario: Say a user has 100 favorite items.
When I do a User.find(id) will I also be retrieving the 100 favorites and the 100 Items?
In case it's important: ruby version 1.9.3, rails version 3.2.11
Can you try has_many => :through?
class User < ActiveRecord::Base
has_many :favorites
has_many :items, :through => :favorites
//other code
end
In your case has_many :through is definitely the way to go. I would recommend reading: http://guides.rubyonrails.org/association_basics.html
Of particular interest with regard to your question:
2.8 Choosing Between has_many :through and has_and_belongs_to_many
Rails offers two different ways to declare a many-to-many relationship between models. The simpler way is to use has_and_belongs_to_many, which allows you to make the association directly:
class Assembly < ActiveRecord::Base
has_and_belongs_to_many :parts
end
class Part < ActiveRecord::Base
has_and_belongs_to_many :assemblies
end
The second way to declare a many-to-many relationship is to use has_many :through. This makes the association indirectly, through a join model:
class Assembly < ActiveRecord::Base
has_many :manifests
has_many :parts, :through => :manifests
end
class Manifest < ActiveRecord::Base
belongs_to :assembly
belongs_to :part
end
class Part < ActiveRecord::Base
has_many :manifests
has_many :assemblies, :through => :manifests
end
The simplest rule of thumb is that you should set up a has_many :through relationship if you need to work with the relationship model as an independent entity. If you don’t need to do anything with the relationship model, it may be simpler to set up a has_and_belongs_to_many relationship (though you’ll need to remember to create the joining table in the database).
You should use has_many :through if you need validations, callbacks, or extra attributes on the join model.
It is better than using has_and_belongs_to_many.
When I do a User.find(id) will I also be retrieving the 100 favorites
and the 100 Items?
No. You'll just get the user object.
Update:
Calling User.include(:favourites, :items).find(id) will get you joined tables in case you want to make many calls to items table from user object.