Skip to content

Instantly share code, notes, and snippets.

@ronanrodrigo
Created June 10, 2013 04:10
Show Gist options
  • Save ronanrodrigo/5746487 to your computer and use it in GitHub Desktop.
Save ronanrodrigo/5746487 to your computer and use it in GitHub Desktop.
Eventos recorrentes no ruby on rails. A criação recorrência de eventos em qualquer ambiente, requer uma avançada lógica de regras. Entre as dificuldades está os Time Zones, UTC e o querido mês de Fevereiro. Pra facilitar tudo isso, existe uma gem chamada Ice Cube. Que irá ajudar a criar uma regra de repetição para um evento. Fonte: http://seejoh…
%fieldset.recurrences
%legend Recurrences
.row-fluid
.span2
= f.input :period_type, input_html: {class: ""}, collection: Dieting::RECURRING_RULES, label_method: :last, value_method: :first, as: :radio_buttons, item_wrapper_class: 'inline btn span12'
.span10.week_days
.row-fluid
= f.input :day, input_html: {class: ""}, label_html: {class: "days-checkbox"}, collection: Dieting::WEEK_DAYS, label_method: :last, value_method: :first, as: :check_boxes, item_wrapper_class: 'inline btn span3'
.span10.month_days
.row-fluid
= f.input :day_of_month, input_html: {class: ""}, label_html: {class: "days-checkbox"}, collection: Dieting::MONTH_DAYS, label_method: :last, value_method: :first, as: :check_boxes, item_wrapper_class: 'inline btn month'
class Dieting < ActiveRecord::Base
include IceCube
attr_accessible :period_type, :recurring_rule, :day, :day_of_month
attr_accessor :period_type, :recurring_rule, :day, :day_of_month
serialize :recurring_rule, Hash
RECURRING_RULES = [[IceCube::Rule.weekly,"Weekly"],[IceCube::Rule.monthly,"Monthly"]]
WEEK_DAYS = {1 => "Monday", 2 => "Tuesday", 3 => "Wednesday", 4 => "Thursday", 5 => "Friday", 6 => "Saturday", 7 => "Sunday"}
MONTH_DAYS = {}
(1..31).to_a.each do |m_day|
MONTH_DAYS[m_day] = m_day.to_s
end
def recurring_rule=(new_schedule)
write_attribute(:recurring_rule, new_schedule.to_hash)
end
def recurring_rule
Schedule.from_hash(read_attribute(:recurring_rule))
end
def day
rule_is_present? ? self.recurring_rule.to_hash[:rrules].first()[:validations][:day] : nil
end
def day_of_month
rule_is_present? ? self.recurring_rule.to_hash[:rrules].first()[:validations][:day_of_month] : nil
end
def period_type
rule_is_present? ? self.recurring_rule.to_hash[:rrules].first[:rule_type].match(/::([\w]+)Rule/)[1] : nil
end
private
def rule_is_present?
self.recurring_rule.to_hash[:rrules].present?
end
end
class DietingsController < ApplicationController
def create
@dieting = Dieting.new(params[:dieting])
create_schedule params, @dieting
respond_to do |format|
if @dieting.save
format.html { redirect_to @dieting, notice: 'Dieting was successfully created.' }
format.json { render json: @dieting, status: :created, location: @dieting }
else
format.html { render action: "new" }
format.json { render json: @dieting.errors, status: :unprocessable_entity }
end
end
end
def update
@dieting = Dieting.find(params[:id])
create_schedule params, @dieting
respond_to do |format|
if @dieting.update_attributes(params[:dieting])
format.html { redirect_to @dieting, notice: 'Dieting was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @dieting.errors, status: :unprocessable_entity }
end
end
end
private
def create_schedule params, dieting
day_rules = {weekly: "day", monthly: "day_of_month"}
schedule = IceCube::Schedule.new(dieting.start, end_date: dieting.end)
period_type = params[:dieting][:period_type].downcase
day_rule = day_rules.with_indifferent_access[period_type]
days = params[:dieting][day_rules.with_indifferent_access[period_type]].reject { |c| c.empty? }
schedule.add_recurrence_rule IceCube::Rule.send(period_type).send(day_rule, days.map(&:to_i)).until(dieting.end)
@dieting.recurring_rule = schedule
end
end
gem 'ice_cube'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment