I need some assistance, I'm working on creating a weekly schedule. But my output is not displaying the desired criteria. Everything is displaying, but it's not assigning the start and end time properly and I can't figure out why. I'm new to ruby so any help would be greatly appreciated. Below is the method from my control and the output in the view.
def generate_schedule
logger.info #generate_schedules
# create hash for view
#generate_schedules = Hash.new
# find current required schedule
schedule_structure = Availability.where(:addressable_type =>'CallCenter',:addressable_id => session[:employee].call_centers.first.id).all
# find all available employee times
employee_availability = Availability.where('priority > 0').where(:addressable_type => 'Employee', :addressable_id => session[:employee].call_centers.first.employees.collect(&:id)).all
# create availability to requirement hash to determine order of days
availability_to_requirement_hash = create_availability_to_requirement_hash(schedule_structure, employee_availability)
# iterate through the hash day by day, a data is no use to us
availability_to_requirement_hash.each do |day,a|
# select the employees with availability for the chosen day, sort them by priority, and then iterate through them to clear the requirements
employee_availability.select{|b| b.day_increment == day}.sort_by{|c| c.priority}.group_by(&:addressable).each do |employee, availabilities|
# select the start time for the current day defined from requirement hash
start_time = schedule_structure.select{|b| b.day_increment == day && b.priority > 0}.first.time_increment
#define the length of the shift
shift_length = employee.length_of_shift > availabilities.length ? availabilities.length : employee.length_of_shift
#define the end time for the shift
end_time = start_time + shift_length
logger.info end_time
#check if employee already defined in hash, if present add the shift as an array of date, start time and end time, if not then add employee to hash with value as array
#generate_schedules.has_key?(employee) ? #generate_schedules[employee] << [day, start_time, end_time] : #generate_schedules[employee] = [[day, start_time, end_time]]
logger.info schedule_structure
#update the schedule structure to reflect the time removed // do not change database
(1..shift_length).each do |d|
schedule_structure.select{|e| e.day_increment == day && e.priority > 0}.first.priority -= 1
end
end
end
end
Here's an example of my output:
Example of View
Related
Newb developer. Need to put some counters on the site that counts the number of times certain songs are played. It's related to the Song model, but doesn't have to be, and not of any one song instance. Just wondering where I put a counter that acts like a constant?
if Subscription.where("band_id = ? and fan_id = ?", #band.id, #fan.id).any? && #fan.donating
#song.total_sub_donate_plays += 1
#song.total_month_sub_donate_plays += 1
site_wide.counter_total +=1
site_wide.counter_total_month += 1
end
If you have memcached/redis setup then use the Rails.cache
http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html#method-i-increment
something like:
if Subscription.where("band_id = ? and fan_id = ?", #band.id, #fan.id).any? && #fan.donating
#song.total_sub_donate_plays += 1
#song.total_month_sub_donate_plays += 1
Rails.cache.increment("stats/counters/total")
Rails.cache.increment("stats/counters/#{Date.current.strftime("%Y/%m")}", {expires_in: 40.days})
end
then later you can:
Rails.cache.read("stats/counters/total")
Rails.cache.read("stats/counters/#{Date.current.strftime("%Y/%m")}")
Another option is to create aggregate data tables. this will let you have more control in the long run.
something like:
class DailySongData
# event_date: date,
# sub_count:integer
# listing_count:integer
end
this will help organize your data for future learning
i am trying to work out how to write a rake tasks that will run daily and find where the days remaining is 0 to update the column amount to zero.
I have the following methods defined in my model, though they don't exactly appear to be working as I am getting the following error in the view
undefined method `-#' for Mon, 27 Jun 2016:Date
def remaining_days
expired? ? 0 : (self.expire_at - Date.today).to_i
end
def expired?
(self.expire_at - Date.today).to_i <= 0
end
def expire_credits
if expired?
self.update(:expire_at => Date.today + 6.months, :amount => 0)
end
end
with the rake tasks i have never written of these and i thought i would be able to call a method of StoreCredit that would expire the points if certain conditions are met but i am not sure how this all works
task :expire_credits => :environment do
puts 'Expiring unused credits...'
StoreCredit.expire_credits
puts "done."
end
# model/store_credit.rb
# get all store_credits that are expired on given date, default to today
scope :expire_on, -> (date = Date.current) { where("expire_at <= ?", date.beginning_of_day) }
class << self
def expire_credits!(date = Date.current)
# find all the expired credits on particular date, and update all together
self.expire_on(date).update_all(amount: 0)
end
end
Since it's a rake task, I think it's more efficient to update all expired ones together
#rake file
result = StoreCredit.expire_credits!
puts "#{result} records updated"
Retrieve Record Count Update
class << self
def expire_credits!(date = Date.current)
# find all the expired credits on particular date, and update all together
records = self.expire_on(date)
records.update_all(amount: 0)
records.length
end
end
You call class method but define instance method. You will need to define class method:
def self.expire_credits
Pretty new to RoR. Wonder if anyone can help me with this issue.
I got a gem called "business_time" which calculates the business days between two dates. I have set up a method in the model which does all the calculations.
I have a field called "credit" which should hold the number of business days. Here's what I have:
MODEL
def self.calculate(from_date,to_date)
days = 0
date_1 = Date.parse(from_date)
date 2 = Date.parse(to_date)
days = date_1.business_days_until(date2)
days
end
CONTROLLER
def new
#vacation = current_user.vacations.build
#vacations = Vacation.calculate(:from_date, :to_date)
end
I got an error referencing something about a string.
Furthermore, how do I go about storing the data from the method into the field called "credit"?
Thanks guys.
I think there is no need for an extra method, since all attributes (from_date, end_date and credit) are stored in the same model.
I would just set from_date and end_date in the initializer and calculate credit with a callback before validation:
# in the model
before_validation :calculate_credit
private
def calculate_credit
if from_date && to_date
# `+ 1` because the user takes off both days (`from_date` and `to_date`),
# but `business_days_until` doesn't count the `from_day`.
self.credit = from_date.business_days_until(to_date) + 1
end
end
# in the controller
def new
#vacation = current_user.vacations.build
end
def create
#vacation = current_user.vacations.build(vacation_params)
if #vacation.save
# #vacation.credit would return the calculated credit at this point
else
# ...
end
end
private
def vacation_params
params.require(:vacation).permit(:from_date, :to_date)
end
What you need here is pass String objects instead of Symbol objects.
So instead of #vacations = Vacation.calculate(:from_date, :to_date), you probably need to pass params[:from_date] and params[:to_date] which should be strings like 20/01/2016, etc...
Your code should be
#vacations = Vacation.calculate(params[:from_date], params[:to_date])
I am iterating through a list of records. I need to check that if a record is first do XYZ and if not do ABC. Unfortunately I cant do this:
user = User.first
or
user = User.find(:id)
user.first?
Solution posted below
1. Make method to grab next and previous records
def next
[Model].where("id > ?", id).first
end
def prev
[Model].where("id < ?", id).last
end
2. Make method to check if record is first
def first?(record)
[Model].first == record
end
3. check if record is first
records.each do |record|
if record.first?(record)
record.update_attributes(attr: record.attr + record.attr)
else
prev_rec = [Model].find(record.id).prev
record.update_attributes(attr: prev_rec.attr + record.attr )
end
end
returns true or false
One improvement i would make sure that [Model].first is persistent so that it doesn't make a call to the database each time the loop is run.
def home
#guide = Guide.all
#finished = Guide.where(:date_starting <= Time.now)
end
Why doesn't this work? In my controller I want to compare the the start date of the objects in my database with the Time now, so that Exhibitions that are no longer on display are in the '#finished' variable. I get the error 'comparison of Symbol with Time failed'.
Thanks
Because the where() method does not do comparisons like you show here.
Your query could be written like so:
Guide.where('date_starting <= ?', Time.now)
or
Guide.where('date_starting <= :now', {now: Time.now})