How to setup the associations for an "Options" model? - ruby-on-rails

If had had the models Store, Product, User and Price with the following associations
class User < ActiveRecord::Base
has_many :products
has_many :stores
has_many :prices
end
class Store < ActiveRecord::Base
belongs_to :user
has_many :prices
end
class Product < ActiveRecord::Base
belongs_to :user
has_many :prices
end
class Price < ActiveRecord::Base
belongs_to :user
belongs_to :product
belongs_to :store
end
class Estate < ActiveRecord::Base
belongs_to :user
end
And want to create a Option model that holds the models specific option type with things like, if an Estate has a backyard, swimming pool, tennis court or a price has a deal, discount or buy one get one free. Would this be done by a polymorphic association?
I'm doing this so I don't have to create a Option model for each model and can just have one model for all new options I want to add. So is this the correct way to go about this?

If you use a polymorphic option model, then the fields would be the same for each class/record an object belongs to. I don't think this is what you want since a deal doesn't have a swimming pool and an estate isn't buy-one-get-one (I wish!).
I would look into using Rails 3.2 and the ActiveRecord::Store feature. With this, just add a single text column to your model(s) (call it "options") and then you can define all the options you need.
class Estate < ActiveRecord::Base
belongs_to :user
store :options, accessors: [ :backyard, :pool, :tennis, :butler, :wine_cellar ]
end
estate = Estate.new
estate.pool = true
estate.options[:number_of_sharks] = 3 # Attributes not defined as accessors work too

Related

how to connect two table that has no relation in rails

I have a table called foods and categories, but this table has no relation, I want to connect them through another table called food_category. And I want to make one-to-one relation between food and category maybe the diagram looks like this
class Food < ApplicationRecord
has_one :category
end
class Category < ApplicationRecord
has_one :food
end
class FoodCategory < ApplicationRecord
belongs_to :category
belongs_to :food
end
Is it possible to do this?
Yes, this is possible. You just need to do
has_one :category, through: :food_categories
as discussed in the Rails docs here.
However, this is a long-winded way to go about this kind of association. If it's going to be one-to-one, why not just add a foreign key to Category from Food? And presumably, you would actually want Category to contain many Food records? Seems like the below would make more sense:
class Food < ApplicationRecord
belongs_to :category
end
class Category < ApplicationRecord
has_many :food
end
class Food < ApplicationRecord
has_one :food_category
has_one :category, through: :food_categories
end
In rails console, you can access like this
Food.find(:id).categories

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

What references, foreign_keys do I need to add for these associations?

I have these associations in my Rails 4.2 app. I don't understand how to setup the proper references/foreign_keys between instructors and courses.
So far both instructors and courses tables have a local_id (local reference).
Local is a training center they both belong to.
class Local < ActiveRecord::Base
has_many :instructors
has_many :courses
end
class Instructor < ActiveRecord::Base
belongs_to :local
has_many :courses, through: :locals
end
class Course < ActiveRecord::Base
belongs_to :local
has_many :instructors, through: :locals
end
Do I add a foreign_key to the courses table? Like this:
add_foreign_key :courses, :instructors
I read something about when having many to many associations we need a "join table" cause we need to store many ids. I guess Local is just that in this case.
Or do I need another table(Model) that belongs_to :instructor, :course?
Here is how I would set it up for maximum flexibility.
Instructors and Courses
Lets set up a many to many relationship with a join model which we call Employment.
We can generate the model with:
rails g model employment instructor:belongs_to course:belongs_to
Which will give us this:
class Employment < ActiveRecord::Base
belongs_to :instructor
belongs_to :course
end
employments will have the instructor_id and course_id foreign keys. This lets us assign any number of instructors to a course and vice versa.
So let's put the join model to use:
class Instructor < ActiveRecord::Base
has_many :employments
has_many :courses, through: :employments
end
class Course < ActiveRecord::Base
has_many :employments
has_many :instructors, through: :employments
end
Venues and Courses
I would recommend you rename your Local model Venue as it's the common english term for the place where a course or event is held. Locale is awkward since it collides with a separate concept in web applications and may cause name clashes.
And we should probably set it up as many to many to account for the complexities of real life.
So again:
rails g model booking venue:belongs_to course:belongs_to
class Booking < ActiveRecord::Base
belongs_to :venue
belongs_to :course
end
bookings will have the venue_id and course_id foreign keys.
class Venue < ActiveRecord::Base # was Local
has_many :bookings
has_many :courses, through: :bookings
end
class Course < ActiveRecord::Base
# ...
has_many :bookings
has_many :venues, through: :bookings
end
More reading:
http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association
http://blog.flatironschool.com/why-you-dont-need-has-and-belongs-to-many/

How to create a Rent in Rails

I am tryng to develop a rent system where a user can login, create products, and his products can be rented by other users.
My problem is, I don't know how to create a rent that retrieves the product_id and customer_id. I made the relations but it isn't working.
I also create the CRUD for each one, even the rent. How can I store the information and pass to the Rent?
I have 4 models:
User
Product
Rent
Category
I created a new column in Rent called customer_id, and I've passed the class "User":
class Product < ActiveRecord::Base
belongs_to :user
belongs_to :category
belongs_to :rents
class User < ActiveRecord::Base
has_many :products
has_many :rents
has_many :customer_id, :through => :rent
class Rent < ActiveRecord::Base
belongs_to :user
belongs_to :product
belongs_to :customer, :class_name => "User"
end
I think I need to create a button that retrieves the information that I need. I searched through the documentation but I couldn't find it.
This line: has_many :customer_id, :through => :rent would never make sense this way in Rails. If you say has_many :customer_id, you are making two mistakes:
Whatever you write after has_many, it should be plural.
If what you write after has_many doesn't correspond directly to a model name as this the case with you, you have to explicit mention the class_name.
Same mistake you are repeating when you say:
class Product < ActiveRecord::Base
belongs_to :rents # it should be rent.
end
And now coming to what you are actually trying to implement:
class Rent < ActiveRecord::Base
belongs_to :user
has_one :product
has_one :customer
end
And in Product and Customer tables, you need to define rent_id as a foreign key. And you should also mention that each of them belongs_to Rent.

How to model table with items which have multiple subcategories?

I need some advice. I am pretty new in modeling database so I was wondering what would be the most convenient way to model database which would make my life easier. I have one Car item which can have multiple descriptive subcategories, like TireCategory, GlassCategory, EngineCategory...
I was thinking about doing something like this:
class Car < ActiveRecord::Base
belongs_to :tire_category
belongs_to :glass_category
belongs_to :engine_category
#Car would have three additional columns: tire_category_id, glass_category_id, engine_category_id
end
class TireCategory < ActiveRecord::Base
has_many :cars
end
class GlassCategory < ActiveRecord::Base
has_many :cars
end
class EngineCategory < ActiveRecord::Base
has_many :cars
end
Is this recommended way to do it or some other relation would be more suitable? Thank you!
You can store cars (with uniq data like model name and sku) in one table, properties (like engines, glasses) in another, and one more table for relation between cars and properties.
class Car < ActiveRecord::Base
has_many :car_properties, dependent: :destroy
has_many :properties, through: :car_properties
end
class Property < ActiveRecord::Base
has_many :car_properties, dependent: :destroy
has_many :cars, through: :car_properties
end
class CarProperty < ActiveRecord::Base
belongs_to :car
belongs_to :property
end
If you have a lot of properties and want to logically separate them then create separate models for each property. Like Engine, Tire, Glass. Each model will contain properties variants. Then create one table for each property to connect it to the car. Like CarEngine, CarGlass. It will contain car_id and property_id (engine_id, glass_id).

Resources