Notification to others on birthday - ruby-on-rails

I want to send notification mail to others whose birthday is not today.
I have used code to find out people having birthday today...
Code for controller:
#people = Person.find(:all, :conditions => ["DAY(date) = ? AND MONTH(date) = ?", Date.today.day, Date.today.month])
Now, how do I modify it to get people other than birthday person?

Surely it should be:
#people = Person.where('DAY(date) <> ? AND MONTH(date) <> ?', Date.today.day, Date.today.month)
Using OR it will exclude people from other months where the day is today and from other days of the current month.

#people = Person.where('DAY(date) <> ? OR MONTH(date) <> ?', Date.today.day, Date.today.month)

#people = Person.where("extract(month from date) != ? AND extract(day from date) != ?", Date.today.month, Date.today.day)

Related

How to get user's birthday based on day and month only

I want to have a member list for today's birthday and upcoming birthday(tommorow).
In users.controller.rb
def birthday
#birthday_users = User.all.order("created_at DESC").where(:birthday => Date.today)
end
def upcoming_birthday
#upcoming_birthday_user = User.all.order("created_at DESC").where(:birthday => 1.days.from_now )
end
These codes work only when the day, month and year are the same as today.
Example:
User 1's birthday = October 3 2018 (Showing on the birthday list)
User 2's birthday = October 3 2000 (Not showing on the birthday list)
In User model
PostgreSql
scope :today_birthday, { where('EXTRACT(month FROM birthday) = ? AND EXTRACT(day FROM birthday) = ?', Date.today.month, Date.today.day).order("created_at DESC") }
scope :upcoming_birthday, { where('EXTRACT(month FROM birthday) = ? AND EXTRACT(day FROM birthday) = ?', 1.days.from_now.month, 1.days.from_now.day).order("created_at DESC") }
MySql
scope :today_birthday, { where('MONTH(birthday) = ? AND DAY(birthday) = ?', Date.today.month, Date.today.day).order("created_at DESC") }
scope :upcoming_birthday, { where('MONTH(birthday) = ? AND DAY(birthday) = ?', 1.days.from_now.month, 1.days.from_now.day).order("created_at DESC") }
I'm assuming you want to find all users having a birthday today. So, you might want to ignore year and only consider month and day while querying. The below code might help you with that:
def birthday
#birthday_users = User.where('EXTRACT(month FROM birthday) = ? AND EXTRACT(day FROM birthday) = ?', Date.today.strftime("%m"), Date.today.strftime("%d"))
end
def upcoming_birthday
tomorrow = Date.today + 1.day
#upcoming_birthday_users = User.where('EXTRACT(month FROM birthday) = ? AND EXTRACT(day FROM birthday) = ?', tomorrow.strftime("%m"), tomorrow.strftime("%d"))
end

Greater/Lower than works but equals doesn't on >= and <= on .where()

I have a Rails 4 app and I'm trying to make a simple search for my invoices with 3 optional arguments: Name of the client, Start Date, End Date.
The search works fine mostly, if I put a start date and an end date it works for < and >, but eventhough i used >= and <=, if the invoice date is the same to either start or end, it just won't show on the result list.
The tables used look like this:
Client Table
ID
Name
The rest of the fields aren't necessary
Invoice Table
ID
Client_ID
Total_Price
Created_At *only here for relevance*
My Invoice Controller Search method looks like this:
def search
if request.post?
#count = 0
#invoices = Invoice.all
if params[:start_date].present?
#invoices = Invoice.invoices_by_date(#invoices, params[:start_date], 'start')
if #invoices.present?
#count = 1
else
#count = 2
end
end
if params[:end_date].present?
#invoices = Invoice.invoices_by_date(#invoices, params[:end_date], 'end')
if #invoices.present?
#count = 1
else
#count = 2
end
end
if params[:name].present?
#invoices = Invoice.invoices_by_client(#invoices, params[:name])
if #invoices.present?
#count = 1
else
#count = 2
end
end
if #count == 2
flash.now[:danger] = "No results found."
#invoices = nil
end
#name = params[:name]
#start_date = params[:start_date]
#end_date = params[:end_date]
end
end
And the Invoice Model methods i use look like this:
def self.invoices_by_client(invoices, name)
invoices= invoices.includes(:client)
.select('invoices.created_at', 'invoices.total_price', 'clients.name')
.where("clients.name LIKE ?", "%#{name}%")
.references(:client)
return invoices
end
def self.invoices_by_date(invoices, date, modifier)
if modifier == 'start'
invoices = invoices.includes(:client)
.select('invoices.created_at', 'invoices.total_price', 'clients.name')
.where("invoices.created_at >= ?", date)
.references(:client)
elsif modifier == 'end'
invoices = invoices.includes(:client)
.select('invoices.created_at', 'invoices.total_price', 'clients.name')
.where("invoices.created_at <= ? ", date)
.references(:client)
end
return invoices
end
It probably isn't the best solution overall and I don't know if i did anything wrong so it would be great if you guys could help me with this.
I followed Alejandro's advice and messed around with the time aswell as the date, something like this:
if modifier == 'start'
invoices = invoices.includes(:client)
.select('invoices.created_at', 'invoices.total_price', 'clients.name')
.where("invoices.created_at >= ?", "#{date} 00:00:00") // Added the start time
.references(:client)
elsif modifier == 'end'
invoices = invoices.includes(:client)
.select('invoices.created_at', 'invoices.total_price', 'clients.name')
.where("invoices.created_at <= ? ", "#{date} 23:59:59") // Added end time aswell
.references(:client)
end
I forced the time for the start date as 00:00:00 and the time for the end date as 23:59:59 and it worked as desired. Thank you for the help man and i hope this helps other people!

Order a model with conditions in Rails (3)

Lets say there is a model called Event. I want to display important and current events first, so i have the attributes important (boolean) and enddate (date).
Now I want to get all events where important == true and where enddate >= today first, all others should be ordered by created_at.
I want to avoid doing events = important_events + not_important_events as this would return an array insted of an activerecord. Does anyone knows an elegant way to order a model in rails?
Try (for ActiveRecord 5+):
#events = Event.where(:important => true, 'enddate >= ?', Date.today).or(Event.where.not(:important => true, 'enddate >= ?', Date.today).order(:created_at => :desc))
Try this, It will return newest record first and fulfil your conditions.
important == true
enddate >= today
#events1 = Event.where(:important => true).where('enddate >= ?', Date.today).order(:created_at => :desc)
#events2 = Event.where(:important => false).where('enddate <= ?', Date.today).order(:created_at => :desc)
#events = #events1.or(#events2)
"OR" works only in ActiveRecod(5+).

Grouping in Rails 4

I have a calendar and I want to group this data..so I have this in my controller
#entry_by_date = Entry.where("emp_mail_addr = ? and emp_first_name = ? and emp_last_name = ? and emp_dept = ?", current_user.email, current_user.emp_first_name, current_user.emp_last_name, current_user.emp_dept).group_by {|i| i.leave_start.to_date}
#date = params[:date] ? Date.parse(params[:date]) : Date.today
Question is for #entry_by_date I have it .group_by {|i| i.leave_start.to_date}
how can I make this have group by two dates for example....
#entry_by_date........group_by {|i| i.leave_start.to_date} {|i| i.leave_end.to_date}
So it will now group by leave_start and leave_end so now on my calendar it will show up with leave start and leave end dates..
I tried doing it like this
#entry_by_date = Entry.where("emp_mail_addr = ? and emp_first_name = ? and emp_last_name = ? and emp_dept = ?", current_user.email, current_user.emp_first_name, current_user.emp_last_name, current_user.emp_dept).group_by {|i| i.leave_start.to_date}
#entry_by_date = Entry.where("emp_mail_addr = ? and emp_first_name = ? and emp_last_name = ? and emp_dept = ?", current_user.email, current_user.emp_first_name, current_user.emp_last_name, current_user.emp_dept).group_by {|i| i.leave_end.to_date}
but only leave start showed up or if I switched them leave end would show up. I would like for both to show up and suggestions are greatly appreciated!!!!
Thank you!
Be aware that there is a critical difference between group_by and group APIs - the former works on lists (after they have been fetched from the database), while the latter is used in the database query itself (adding it a GROUP BY clause)
I'm not sure what you are trying to achieve, but if you want to have the keys of your group to be an array of dates, you could do it in a single group_by block:
#entry_by_date = entries.group_by { |i| [i.leave_start.to_date, i.leave_end.to_date] }
If you want each entry to be grouped twice (once with its start date, and once with its end date), you need to create 2 grouped maps, and join them:
entry_by_start_date = entries.group_by {|i| i.leave_start.to_date}
entry_by_end_date = entries.group_by {|i| i.leave_end.to_date}
#entry_by_date = entry_by_start_date.merge(entry_by_end_date) {|key, oldval, newval| newval + oldval}

Rails: How to loop through month?

I made a scope help me to select objects
scope :best_of_the_month, ->(year, month) do
time = Time.new(year, month)
start_time = time.beginning_of_month
end_time = time.end_of_month
where("created_at > ? AND created_at < ?", start_time, end_time).where("likes > ?", 15).where("rating > ?", 4.85).order_by_rating.to_a.uniq(&:author)
end
Then, I want to loop through this method, from 2014/1 to now. How can I do it?
Maybe something like this:
start_date = Date.create(2014,1).month
end_date = Date.today.month
#monthly_videos = []
(start_date..end_date).each do |year, month|
videos = Video.best_of_the_month(year, month)
#monthly_videos << videos
end
I find a solution here, How to Loop through Months in Ruby on Rails. But it seems about looping through the days. Not the month
With the best_of_the_month scope defined to take month and year as params, the following code should work:
date = Date.new(2014,1,1)
#monthly_videos = []
while true
videos = Video.best_of_the_month(date.year, date.month)
#monthly_videos << videos
date += 1.month
break if date == Date.today.beginning_of_month
end
You could use the Date#next_month method
date = Date.new(2014,1,1)
final_date = Date.new(Date.today.year, Date.today.month)
#monthly_video = []
loop do
#monthly_videos << Video.best_of_the_month(date.year, date.month)
break if date == final_date
date = date.next_month
end

Resources