I'm trying to do a "ecommerce like" solution. When a product is defined, there are many option_values, e.g. whip cream => yes.
When I'm creating a line_item, my associations are like this.
class LineItem < ActiveRecord::Base
belongs_to :cart
belongs_to :order
belongs_to :product
belongs_to :shop
...
When a user chooses a product, he chooses options_values and a line_item must be created to store this.
Currently I'm not sure what is a good way to model the option_values in a line item.
My gut instinct is that a line_item has_many option_values, but it would seem weird to store foreign keys in option_values. The other thought is that line_item habtm option_values.
What would be a good way to model this line_item has_many option_values relationship, ideally storing the reference in the line_items table?
If your option_values are always boolean (whip cream => yes) you should have an OptionValues model with all available option_values and do habtm between LineItem and OptionValues.
If your option values are not always boolean (sugar => 2.spoons) then you must store this value (2.spoons) in the join model, so you should do something like this:
class LineItem < ActiveRecord::Base
has_many :line_item_option_values
...
end
class LineItemOptionValue < ActiveRecord::Base
belongs_to :line_item
belongs_to :option_value
end
class OptionValue < ActiveRecord::Base
has_many :line_item_option_values
end
And have the table for LineItemOptionValue a field for the value of the option.
Related
Three models:
class Order < ActiveRecord::Base
belongs_to :product
belongs_to :sale
end
class Sale < ActiveRecord::Base
has_many :orders
accepts_nested_attributes_for :orders, :reject_if => :all_blank
end
class Product < ActiveRecord::Base
belongs_to :greenhouse
has_many :orders
end
First a product is created. Then, an order can be made with one Product. Then, what I expect to be is, the Sale is filled with many Orders. But, when saving the Sale, it only ignores the Orders attached.
I've only found examples when the Sale creates the Order, or the parent object creates the Child object, but in this case, the child object, or the Order is already created, and only needs to be assigned or related with the new Sale.
How can I relate the child object with a new parent?
Just be sure that you have permit params at your SalesController something like this:
params.require(:sale).permit(:each, :sale, :field, :as, :symbol, :and, orders_attributes: [:each, :order, :field, :as, :symbol])
This is the most common issue which gives the described behavior. If not, we need some more information.
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.
I have two models: Person, and Property. In the Person model I have a field which stores the role of the person(tenant, owner, admin, contractor, etc). Since each property will belong to an owner and potentially have one or more tenants, I thought this would be a good opportunity to use the HABTM model relation.
Do I have this right?
Also, how do I reference the attached model? Assuming my join model is named PropertiesPeople, and I wanted to fetch the tenants for a particular property, would that be the following?
#property.people.where(:role => "tenant")
If the same Person can have more than one Property, you should can use HABTM. Something like this:
class Person < ActiveRecord::Base
# in the people table you are storing the 'role' value
has_and_belongs_to_many :properties, join_table: 'people_properties'
end
class Property < ActiveRecord::Base
has_and_belongs_to_many :people, join_table: 'people_properties'
end
You should create the intermidiate table people_properties with the foreign keys, person_id and property_id.
The problem of this approach is that if a Person can be "tenant" in one property and "contractor" in another, for example, you can't store that information. In that case I will suggest using an intermidiate model, like this
class Person < ActiveRecord::Base
has_many :property_people
has_many :properties, through: :property_people
end
class PropertyPerson
# now you store here the 'role' value
belongs_to :person
belongs_to :property
end
class Property < ActiveRecord::Base
has_many :property_people
has_many :people, through: :property_people
end
I don't know for sure if the class names are successfully inferred from the relationships names, in that case you can always indicate class_name or even the foreign_key for the associations. Also you can indicate the table for a model, using self.table_name=
I am creating a Shopping Cart.
So I will have a model called LineItem.
Each instance of a cart will have 1+ line items. As will a completed transaction - which becomes an 'order'.
So, in theory, a LineItem belongs_to Cart and also belongs_to Order.
But, what would the DB table look like? a cart_id and order_id in my LineItems table?
That would mean that for every valid cart record, there will be an order_id that is nil (or empty). Likewise, for every valid order, there will be an empty cart_id.
This seems like a non-Railsy way to do this.
What is the best way to do this? A polymorphic association? What would that look like if I should do that?
The line item model can have two belongs_to associations
class LineItem < ActiveRecord::Base
belongs_to :cart
belongs_to :order
end
But this can get messy if it needs to belong to several different classes. The solution is polymorphic association which allows a model to belong to more than one model on a SINGLE association, which in the example below is :line_itemable. It will add two attributes, line_itemable_id and line_itemable_type to the LineItem model.
class LineItem < ActiveRecord::Base
belongs_to :line_itemable, :polymorphic => true
end
class Order < ActiveRecord::Base
has_many :line_items, :as => :line_itemable
end
class Cart < ActiveRecord::Base
has_many :line_items, :as => :line_itemable
end
If cart and order share similar attributes such as cost, then another option is to eliminate the order class and simply add a :paid flag on the cart.
I would suggest polymorphic association.
class LineItem < ActiveRecord::Base
belongs_to :owner, :polymorphic => true
end
class Order < ActiveRecord::Base
has_many :line_items, :as => :owner
end
class Cart < ActiveRecord::Base
has_many :line_items, :as => :owner
end
you will need to add owner_type and owner_id to line_items table.
Refer this
I am so surprised of getting -1 for my questions. They are not simple, they are complex.
My line_items table have product_id cart_id order_id
Whenever customer clicks on product, it is added to the cart.
But my apartment, cars, tour package are not products. Whoever is thinking that somehow I can connect to products my cars, apartments tell me. They have fundamentally different attributes. When customers clicks on apartments and chooses 2 bedroom lets say how I can add to line_items my apartment_id or car_id or tour_id. Please I don't need theory on STI or multiple inheritance. I need exactly answer. Thanks for rails expert.
First of all you should format your question regarding to the SO guidelines, that's maybe because you're getting downvotes...
Anyway, I think you're looking for polymorphic associations.
Assuming that Product is meant to be a product available in your shop and LineItem represents a product in an order:
class LineItem < ActiveRecord::Base
has_one :product # ONE LineItem references ONE product in the shop
belongs_to :cart # respectively belongs_to :order
end
class Cart < ActiveRecord::Base
has_many :line_items # ONE Cart HAS MANY LineItems
end
class Product < ActiveRecord::Base
belongs_to :buyable, :polymorphic => true
# here you would have general attributes representing a product, e.g. 'name'
end
class Car < ActiveRecord::Base
has_one :product, :as => :buyable
# here you would have specific attributes in addition to the general attributes in
# product, e.g. 'brand'
end
class Apartment < ActiveRecord::Base
has_one :product, :as => :buyable
# here you would have specific attributes in addition to the general attributes in
# product, e.g. 'address'
end
To make that work your products table must have the two columns
buyable_type (string)
buyable_id (integer)
So in your code you can check what exactly your Product is by doing
#product = Product.find(params[:id])
if #product.buyable.is_a? Car
puts #product.buyable.brand
elsif #product.buyable.is_a? Apartment
puts #product.buyable.address
end