How do I validate an unavailable period - ruby-on-rails

I'm practicing rails and I would like to know how I would validate a situation.
In this case, it's a car rental project. I have a table of Cars (Autos) and one of Unavailable Period.
When registering a car, I assume that the car is available 100% of the month. If someone rents in a certain period, it must be unavailable so it can't be rented again in the same period, how would I do this validation?
Model
class UnavailablePeriod < ApplicationRecord
belongs_to :auto
end
class Auto < ApplicationRecord
belongs_to :rental_company
belongs_to :category
has_many :unavailable_periods
end
Any suggestion? content tip to study this?
What would be the best way?
model

Instead of an UnavailablePeriod I would simply have a Rental model that has a rented_from and a rented_until columns (both datetime).
On creation of a new Rental you then only have to check that there is no existing, date overlapping rental. to check that you could use a custom validation like this:
class Rental < ApplicationRecord
belongs_to :auto
validate :rental_period_is_available
private
def rental_period_is_available
return unless Rental
.where.not(id: id)
.where("rented_from < ? && ? < rented_until", rented_until, rented_from)
.exist?
errors.add(:base, "Car is already booked in this time period")
end
end
I suggest reading about custom validations and validations in general in the offical Rails Guides.

Related

rails association limit record based on an attribute

As you can see in the schema below, a user can create courses and submit a time and a video (like youtube) for it, via course_completion.
What I would like to do is to limit to 1 a course completion for a user, a given course and based one the attribute "pov" (point of view)
For instance for the course "high altitude race" a user can only have one course_completion with pov=true and/or one with pov=false
That mean when creating course completion I have to check if it already exist or not, and when updating I have to check it also and destroy the previous record (or update it).
I don't know if I'm clear enough on what I want to do, it may be because I have no idea how to do it properly with rails 4 (unless using tons of lines of codes avec useless checks).
I was thinking of putting everything in only one course_completion (normal_time, pov_time, normal_video, pov_video) but I don't really like the idea :/
Can someone help me on this ?
Thanks for any help !
Here are my classes:
class CourseCompletion < ActiveRecord::Base
belongs_to :course
belongs_to :user
belongs_to :video_info
# attribute pov
# attribute time
end
class Course < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_many :courses
has_many :course_completions
end
You could use validates uniqueness with scoping Rails - Validations .
class CourseCompletion < ActiveRecord::Base
belongs_to :course
belongs_to :user
belongs_to :video_info
validates :course, uniqueness: { scope: :pov, message: "only one course per pov" }
# attribute pov
# attribute time
end

Updating Tickets count from the Bookings model method

I'm creating a ticket booking app for my sample project using Ruby on Rails 4.1. Three are three models - Events, Tickets and Bookings. Events have many tickets and bookings. Tickets have many bookings and they belong to events. Bookings belongs to events and tickets.
Here's the ticket model:
class Ticket < ActiveRecord::Base
belongs_to :event
has_many :bookings
def maximum_tickets_allowed
(1..maximum_quantity.to_i).to_a
end
end
One of the model methods in Booking.rb is:
class Booking < ActiveRecord::Base
belongs_to :event
belongs_to :ticket
has_many :charges
def check_ticket_count
count = ticket.ticket_quantity.to_i - order_quantity.to_i
ticket.ticket_quantity = count
end
This method is used to print the number of remaining tickets after a successful and it works fine. I would like to know what's the best way to update the total tickets (ticket_quantity field in my table) with this value. I have seen some examples where they do it in controller. What's the Rails way?
I tried using ticket.ticket_quantity.save! and ticket.ticket_quantity.update etc. in the same model method but I encounter errors while doing it. Also, it would be great if you could point me to a resource that explores model methods in depth.
Currently you are not saving the ticket so the update is discarded.
Have you tried
count = ticket.ticket_quantity.to_i - order_quantity.to_i
ticket.update_attribute(:ticket_quantity,count)
update_attribute does not require a save as it auto saves without validations.
Although you should probably validate that the order_quantity is <= ticket_quantity
such as
class Booking < ActiveRecord::Base
...
#just threw this in for you too
after_create :update_ticket_count
validates :order_quantity, numericality:{less_than_or_equal_to: ->(booking){ booking.ticket.ticket_quantity}}
def update_ticket_count
ticket.update_attribute(:ticket_quantity,ticket.ticket_quantity.to_i - self.order_quantity)
end
end

Rails 4.1 nested model form fields

Booking -< Orders -< Transactions
class Booking < ActiveRecord::Base
has_many :orders
end
class Order < ActiveRecord::Base
belongs_to :booking
has_many :transactions
end
class Transaction < ActiveRecord::Base
belongs_to :order
end
I need to be able to create a Transaction without an Order or Booking existing.
I'm trying to achieve the following:
When a Transaction is created an Order and a Booking is automatically created. The transaction form can take a Booking.booking_number which will be saved to the above automatically created Booking.
I'm very new to rails and have tried a combination of accepts_nested_attributes_for, Ryan Bates' nested model form part1 screencast and form_fields_for without success.
Some guidance, not necessarily code, would be much appreciated.
My routes look like:
I need to be able to create a Transaction without an Order or Booking
existing.
Bad system design - surely a transaction would follow an order or booking?
From your question, I'd highly recommend creating a booking or order first. This will allow you to create a transaction as a bolt-on to the order or booking:
#app/controllers/bookings_controller.rb
Class BookingsController < ApplicationController
def create
booking = Booking.new(booking_params)
booking.save
end
end
#app/models/booking.rb
Class Booking < ActiveRecord::Base
before_create :build_transaction #-> creates a blank transaction which can be populated later
end
Nonetheless, there's nothing stopping you creating a transaction & assigning an order later
You can do this:
#app/controllers/transactions_controller.rb
def create
Transaction.new(transaction_params)
end
#app/models/transaction.rb
Class Transaction < ActiveRecord::Base
after_create :order
def order
self.order.create!([order_details?])
end
end
If you tell me some more about what you're building, I'll be able to create a more refined response!
Try this it may be work.
In your model
accepts_nested_attributes_for :order, :allow_destroy => true
change whether true/false depending on your form

Must i use a polymorphic setup?

I have a app setup question: (for a travel site)
My models are
class User < ActiveRecord::Base
end
class House < ActiveRecord::Base
end
class Apartment < ActiveRecord::Base
end
class Boutique < ActiveRecord::Base
end
class City < ActiveRecord::Base
end
class Activity < ActiveRecord::Base
end
I want to add a "i've been there", "i've done that", "i want to go there" ect to the user model. So when a user/visitor is by example on the activity show page there is a function where they can add the status describe above.
Where do i start in relation with my db setup...must i use the polymorphic setup?
Thanks..remco
I believe we need more information as to how the models relate to each other rather than just saying "I want to add I've been there, I've done that". We need relevant information i.e. A user has_many ???? A house belongs_to ???. Please see ActiveRecord Association basics. This will help gain some more clarity on what you are trying to do.

RoR Vocabulary quiz application scalability

I am designing a vocabulary quiz application in ruby/rails.
I have basic model/association setup which will work, but i am worried about scalability.
There will be a set number of words in the application. For simplicity, lets say 100.
A user will be able to proceed to a question, which will be generated from looking at which questions they have had before. The question will provide a word and 4 choices for the definition (one being the definition, three other definitions being randomly chosen).
Here is the way my models and associations are set up currently;
class User < ActiveRecord::Base
has_many :user_questions
end
class UserQuestion < ActiveRecord::Base
belongs_to :user
belongs_to :vocab_word
end
class VocabWord < ActiveRecord::base
has_many :user_question
end
Assuming i were to keep this basic model, which of the following approaches should i use?
Have a set number of UserQuestion objects (100) per user and use
calculated columns to store statistics the users performance on
particular words. (e.g. user 502 has attempted the word 'arid' 3
times and correctlty answered 2 times).
For each question
attempt, create a new UserQuestion object. (e.g. user 502 attempted
to guess 'arid' and was incorrect)
Are either of these approaches scalable? If the application had one million users, the first strategy would have 100 million rows in user_questions. the second could have much more than that.
You're almost there. I would recommend extending your model with the following, plus the slight correction on UserQuestion and User association.
class User < ActiveRecord::Base
has_and_belongs_to_many :user_questions
end
class UserQuestion < ActiveRecord::Base
has_and_belongs_to_many :users
belongs_to :vocab_word
end
class VocabWord < ActiveRecord::base
has_many :user_question
end
class Attempt < ActiveRecord::base
belongs_to :vocab_word
belongs_to :user
belongs_to :user_question
attr_accessible :result
end
You'd need a user_questions_users association table to have a many-to-many association between questions and users. I believe it would be scalable. Make sure you set your indexes correctly.

Resources