Display all the records when due date is less than current date in Rails - ruby-on-rails

I am having a Quote model which consists of due_date and other fields.
I need to write a condition where we have to display all the records where due_date (which is date data type and stored in database as yyyy-mm-dd format) is less than current date.
For example, current_date is today's date, so I need to display all the records till yesterday.
I wrote a condition but didn't work, can you tell me where I went wrong?
def past_quotes
#items = []
current_date = Time.now.strftime("%Y-%m-%d")
daily_items = Quote.by_account(#account).active.includes(:company).where('due_date' < current_date)
#items << Item.new(items: daily_items) unless daily_items.empty?
end
But still displaying all the records, I think condition is wrong.

You shouldn't use a string when comparing the dates. ActiveRecord should be able to handle dates directly
daily_items = Quote.by_account(#account).active.includes(:company).where('due_date < ?', Date.today)

Can you try following query:
def past_quotes
#items = []
daily_items = Quote.by_account(#account).active.includes(:company).where('due_date < DATE(?)', Time.now)
#items << Item.new(items: daily_items) unless daily_items.empty?
end

Related

Allocate daily sales to date created

Im trying to gather all sales made within a week and put each sale in day made. If Moday was two sales, then Monday => {...}, {...} etc
"Monday" would be ruby's date format.
In my db I have 5 sale objects: Two sales on Monday and two on Tuesday.
Controller:
def daily_customer_sale(created)
date_and_id = Sale.where('created_at >= ?', created).pluck(:created_at, :id)
date_and_id.each do |obj|
yield(obj.first, obj.last)
end
end
def daily_sales(created=nil)
sales_by_date = Hash.new(0)
daily_customer_sale(created) do |date, id|
s_date = date.to_date
sales_by_date[s_date] = Sale.find(id) # Seems to return only one object per day
end
return sales_by_date
end
For views:
daily_sales(1.week.ago.to_datetime)
What I get in two dates (correct) in which each data has only one object when it should be two or more per date. Is there something wrong?
You don't need complex logic to do it. Here is a cleaner way
Sale.where('created_at >= ?', created_at).group_by{ |sale| sale.created_at.to_date}
It will return All the sales grouped by day.
key will be date object and for each day there will be sale array containing all of the sales for that day.
If you need string based key you can format it as you like as per below
Sale.where('created_at >= ?', created_at).group_by{ |sale| sale.created_at.to_date.to_s } #default date format
Sale.where('created_at >= ?', created_at).group_by{ |sale| sale.created_at.to_date.strftime("%d/%m/%Y") } #23/09/2016
You can have a look at Group by method

Rails 4 - How to get specific records based on where conditions

I have a Sale model with an :offer_end column with a date data type. I would like to display specific records of Sale where :offer_end >= Date.today. I tried to get this to work in the controller but im not sure what is the correct syntax to achieve this. This is what im currently doing which isnt working:
def index
#shops = Shop.all
#sales = Sale.where("offer_end >= Date.today", {offer_end: params[:offer_end]})
end
First of all you can't pass the Date.today as a string to the query, it will be passed to the database and it won't understand it.
The query should be something like this
#sale = Sale.where('offer_end > ?', Date.today)
The Date.today will be evaluated then passed as a value to the query.
You could replace the Date.today with any date object or date string, which in your case seems to be in theparams[:offer_end]
#sale = Sale.where('offer_end > ?', params[:offer_end])
You can use scope for these type of operations:
class Sale < ActiveRecord::Base
scope :get_products, ->(date){where(" sales.offer_end >= ? ", date)}
end
In controller you can use this scope as below:
#sales = Sale.get_products(params[:offer_end])
or you can use it directly in controller:
#sales = Sale.where("offer_end >= ?", Date.today)
and you can use params[:offer_end] instead of Date.today

Rails: How to use includes with conditions?

I have a ressource Room that has_many reservations. Likewise the ressource Reservation belongs_to a room.
My reservation model has a starts_at and an ends_at attribute.
In my index action for the Room controller I want to get all the Rooms and include all the reservations for a certain date(the date is given as a parameter).
I have tried this code, but it doesn't seem to work as intended.
#rooms = Room.includes(:reservations).where("reservations.starts_at" => params[:date])
I am aware that this code does not take into account that a room could be reserved for multiple days, but I had to start somewhere.
SUM UP
Based on a date the action should return all the rooms, but only include the reservations that is relevant for that date.
EDIT
This is what I ended up doing.
controllers/rooms_controller.rb
def index
#rooms = Room.includes(:reservations)
#date = params[:date] ||= Date.today
end
views/rooms/index.html.haml
- #rooms.each do |room|
- room.reservations.relevant(#date).each do |reservation|
= reservation.id
models/reservation.rb
def self.relevant(date = Date.today)
if date.blank?
date = Date.today
end
where(
'(starts_at BETWEEN ? AND ?) OR (ends_at BETWEEN ? AND ?)',
date.to_date.beginning_of_day, date.to_date.end_of_day,
date.to_date.beginning_of_day, date.to_date.end_of_day
)
end
It works alright, but the view is talking to the model I think?
If your where conditions refer to another table then you also need to need to specify references as well as includes. e.g.
#rooms = Room.includes(:reservations).
where("reservations.starts_at" => params[:date]).
references(:reservations)
See the API documentation here.

Checking a hash for the existence of a matching value

I'm building a school calendar that lists classes ("sections") and displays semester and exam dates for those classes. The calendar is fed a hash that is defined in the Section.rb model:
def get_calendar
calendar = {}
calendar[:semesters] = Semester.where(section_id: self.id)
calendar[:exams] = Exam.where(section_id: self.id)
{ :calendar => calendar }
end
The Semester and Exam objects have a name, start_date and end_date.
When looping through each day of the calendar, how can I check if there's a semester or exam with a start_date or end_date for that day of the loop?
If there is a semester or exam with either a start_date or end_date that matches the calendar date, I would to display the name.
The calendar dates and the start_date and end_date fields all use the Date class (link).
I sincerely appreciate the help. I can clarify the question if needed :)
Thank you!
Maybe you should re-think your hash, and use it this way:
def get_calendar
semesters = self.semesters
exams = self.exams
events = { }
(semesters + exams).each do |event|
start_date = event.start_date.to_s
events[start_date] ||= []
events[start_date] << event
end_date = event.end_date.to_s
events[end_date] ||= []
events[end_date] << event
end
events
end
And test the presence of an event in the loop that constructs the Calendar:
dates_of_calendar.each do |date|
if #events[date.to_s].present?
# well, there is an event happening for this date! treat it as your wishes!
end
# etc...
end
Would the enumberable detect method work? http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-detect
So as your looping through your condition could be...
semesters.detect{|s| s.begin_date > cal_begin_date ... //more conditions here} &&
exams.detect{|e| e.begin_date > cal_begin_date ... //more conditions here}

Rails filter by date with MetaSearch

I have some records which I show in a view. They have start_date and end_date.
When I access the view, by default I want it only to show records who's dates are not expired.
Expired being defined as:
End date and start date <= Now, and
End date is later than the start date
I then want to have a checkbox that shows all records including the ones that have been expired.
How do I approach this?
In your controller action, you want to have this somewhere:
params[:search] ||= {} # make sure this is instantiated
# filter to show the expired records
if params[:include_expired] # check if the checkbox is checked
params[:search][:end_date_lte] = Date.today # end_date <= Now
params[:search][:start_date_lte] = Date.today # end_date <= Now
end
#records = params[:include_expired] ? RecordClass.where("end_date > start_date").search(params[:search]) : RecordClass.search(params[:search])
You could also bypass all the search things and just use a scope like this:
#records = params[:include_expired] ? RecordClass.expired : RecordClass.all # or whatever logic you need
# scope in the RecordClass
scope :expired, where("end_date > start_date AND end_date <= ?", Date.today)

Resources