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.
Related
I have a model called Company, this model is used for both companies and clients, I know this is not the best approach for companies/clients but the software I'm working on was built that way and to change that, it would take months of job.
class Company < ActiveRecord::Base
has_many :companies
belongs_to :company
has_many :orders, dependent: :destroy
end
My other model is Orders, where the companies are linked by the company_id column and the customers by the customer_id column, that is, an order is linked to a company and a customer of that company.
class Order < ActiveRecord::Base
belongs_to :company
end
Currently, I created a method to get the customer but I would like to call a has_one to get the customer from the order, but I am not able to point the customer_id column of the order to the company id column using the rails class_name.
If I understand your question correctly (in the first para you mentioned clients and in the second you are saying customers so I am assuming clients == customers and customer is also a Company object) you are trying to do this:
class Order < ActiveRecord::Base
belongs_to :company
has_one :customer, class_name: 'Company'
end
which seems incorrect as it should be belongs_to:
class Order < ActiveRecord::Base
belongs_to :company
belongs_to :customer, class_name: 'Company'
end
This should work but you can also specify foreign_key:
belongs_to :customer, class_name: 'Company', foreign_key: :customer_id
From the docs: https://api.rubyonrails.org/v7.0.2.4/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_one
has_one specifies a one-to-one association with another class. This method should only be used if the other class contains the foreign key. If the current class contains the foreign key, then you should use belongs_to instead.
We have a Real-Estate app in which the User can be a Renter or Landlord(Owner). Renters can search for specific houses listed by the Owners. Renters can also add other persons(friends or acquaintances who are staying with that specific renter). In the app we treat them as Coapplicants.
Models
# user.rb
class User < ActiveRecord::Base
has_one :renter
has_one :owner
end
# renter.rb
class Renter < ActiveRecord::Base
belongs_to :user
has_many :coapplicants
end
# coapplicant.rb
class Coapplicant < ActiveRecord::Base
belongs_to :renter
end
Now as to increase the number of users for the app,we implemented a mailing system which sends an Welcome Mail(when the Renter adds a Coapplicant) to signup as a User.And that Coapplicant can choose to be Renter and can add many Coapplicants too. And the process goes on again resulting in increasing the users.
It's like a tree structure and now I want to set-up a perfect database relations(associations) to track the users flowing in and through which renter/coapplicant they are coming.
Now the Current Model structure(not yet developed) looks like this
# user.rb
class User < ActiveRecord::Base
has_one :renter
has_one :owner
end
# renter.rb
class Renter < ActiveRecord::Base
belongs_to :user
has_many :coapplicants
has_many :coapp_renters,
:through => :coapplicants
has_many :inverse_coapplicants,
:class_name => "Coapplicant",
:foreign_key => "coapp_renter_id"
has_many :inverse_coapp_renters,
:through => :inverse_coapplicants,
:source => :renter
end
# coapplicant.rb
class Coapplicant < ActiveRecord::Base
belongs_to :renter
belongs_to :coapp_renter,
:class_name => "Renter"
end
I guess i messed up things a bit. Which database-relationships(associations) would be the best for my current situation.
Can someone throw some light on this please.I'm thinking about using the ancestry gem but how to implement to my current situation.
I've found that sometimes even a small change in perspective when designing your associations can make them flow a lot more naturally.
You have focused exclusively on person entities; User.find(1).renter for example isn't very intuitive, since both models depict essentially the same person.
Instead of trying to model what people are, I would try to model what they have. In this case, instead of a User having a Renter, let them have many Rentals:
class User < ActiveRecord::Base
has_many :rentals,
foreign_key: 'renter_id'
end
class Rental
belongs_to :renter,
class_name: 'User'
belongs_to :property
end
I assume here that you have a model Property that stands for what is being rented - leave that out if it doesn't exist.
It's the same thing for owners. A User becomes an owner just by having Ownerships:
class User < ActiveRecord::Base
has_many :ownerships,
foreign_key: 'owner_id'
end
class Ownership
belongs_to :owner,
class_name: 'User'
belongs_to :property
end
A co-application is slightly different in that it belongs to a Rental:
class CoApplication
belongs_to :co_applicant,
class_name: 'User'
belongs_to :rental
end
class Rental
has_many :co_applications
end
class User < ActiveRecord::Base
has_many :co_applications,
foreign_key: 'co_applicant_id'
has_many :received_co_applications,
through: :rentals,
source: :co_applications
end
Now your Users can be owners, renters, co-applicants - all at the same time. And these associations allow you to capture everything that happened - who signed on whom through what is just a matter of chronological order.
From here on it's a matter of nesting your has_many :through associations to get whatever you want.
Want to know the properties a landlord owns?
has_many :owned_properties,
through: :ownerships,
source: :property
The rentals to her properties?
has_many :leases,
through: :owned_properties,
source: :rentals
The people who rented her properties?
has_many :renters,
through: :leases,
source: :renter
Same thing with co-applications. Want to know who co-applied with a user?
has_many :co_applicants,
through: :received_co_applications,
source: :co_applicant
I would refactor your code and make the co-applicants just a renter that is a child of another renter
in your renter model you have to add a "parent_id" to know whom the co-applicants belongs to.
now in your model you can do something like
#renter.rb
class Renter < ActiveRecord::Base
belongs_to :user
has_many :children, :class_name => "Renter"
belongs_to :parent, :class_name => "Renter"
end
# Example calls
Renter.first.children
Renter.first.parent
I hope this helps
Create a table called Relationship (or something) with two foreign_ids concerning what you want the User and Renter to be able to do with one another (example to be able to "Follow" one another => Follower_id and Following_id). Define methods in your Models related to those ids and then call those methods in your views to display the relations.
I'm a beginner in Rails and I have a problem with ActiveRecords associations.
I'm creating simple car rental service and I made the following associations:
class Client < ActiveRecord::Base
has_many :rentals
has_many :bookings
has_many :cars, :through => :rentals
has_many :cars, :through => :bookings
end
class Rental < ActiveRecord::Base
belongs_to :client, dependent: :destroy
has_one :car
end
class Booking < ActiveRecord::Base
belongs_to :client, dependent: :destroy
has_one :car
end
What I need is to have a car belonging to many bookings and rentals while every booking and rental can have only one car assigned.
class Car < ActiveRecord::Base
# belongs_to_many :bookings
# belongs_to_many :rentals
end
How should I do that?
If a car can have many bookings/rentals, but a booking/rental can only have one car, you're looking at a classic belongs_to/has_many situation. It looks like you're being tripped up by the distinction between belongs_to and has_one -- it's not a grammatical one, but a matter of where the foreign key column is located in your database.
belongs_to: "I am related to exactly one of these, and I have the foreign key."
has_one: "I am related to exactly one of these, and it has the foreign key."
has_many: "I am related to many of these, and they have the foreign key."
Note that has_one and has_many both imply there's a belongs_to on the other model, since that's the only option where "this" model has the foreign key. Note also that this means has_one should only be used when you have a one-to-one relationship, not a one-to-many.
Taking this into consideration, I would replace the has_one :car with belongs_to :car in both your Rental and Booking models, and place has_many :bookings and has_many :rentals in your Car model. Also ensure that your rentals and bookings tables have a car_id column; there should be no rental- or booking-related columns in your cars table.
Yes, there is a "belongs_to_many" in Rails, sort of. It's a little more work and you can't use generators with it. It's called a polymorphic association.
Even though you could make a car have many bookings & rentals, you could associate the car by making it belong to a polymorph such as rentable_vehicle. Your code would look like this
class Car < ActiveRecord::Base
belongs_to :rentable_vehicle, polymorphic: true
end
class Rental < ActiveRecord::Base
belongs_to :client, dependent: :destroy
has_many :cars, as: :rentable_vehicle
end
class Booking < ActiveRecord::Base
belongs_to :client, dependent: :destroy
has_many :cars, as: :rentable_vehicle
end
You can't do belongs_to_many. The closest you can really get is has_and_belongs_to_many, but I'm not sure that's what you want here - unless you can have multiple cars per rental/booking. Check out the guide for a full explanation.
I'd change it up like this:
class Rental < ActiveRecord::Base
belongs_to :client, dependent: :destroy
belongs_to :car
end
class Booking < ActiveRecord::Base
belongs_to :client, dependent: :destroy
belongs_to :car
end
class Car < ActiveRecord::Base
has_many :bookings
has_many :rentals
end
Also, I don't know how your rentals relate to bookings, but my immediate thought is that there should be some relationship between the two, because you probably can't have a rental without booking it, right?
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
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.