class Conference < ActiveRecord::Base validates :title, presence: true, uniqueness: true validates :email, presence: true, format: {with: /\A[^@]+@[^@]+\z/} validates :description, presence: true validates :planned_cfp_end_date, presence: true validates :start_date, presence: true validates :end_date, presence: true validate :start_date_is_before_end_date validate :planned_cfp_end_date_is_before_start_date translates :title, :description has_many :tracks has_many :halls has_many :event_types has_many :events has_many :volunteer_teams has_many :volunteers has_one :call_for_participation, dependent: :destroy has_many :participants, -> { uniq }, class_name: 'User', through: :events has_many :participant_profiles, class_name: 'PersonalProfile' has_many :slots, through: :halls accepts_nested_attributes_for :tracks, :halls, :event_types, :volunteer_teams, reject_if: :all_blank, allow_destroy: true after_create :create_call_for_participation def submissions_grouped_by_day submissions = events.group('date(events.created_at)').select('date(events.created_at) as created_at, count(events.id) as number') submissions.group_by { |s| s.created_at.to_date } end def submissions_grouped_by_confirmation_day submissions = events.joins(:proposition).approved.confirmed.group('date(propositions.confirmed_at)').select('date(propositions.confirmed_at) as confirmed_at, count(events.id) as number') submissions.group_by { |s| s.confirmed_at.to_date } end def update_vote_data! ConferenceVoteSummary.new(conference: self).save end def has_vote_results? vote_data_updated_at.present? end private def planned_cfp_end_date_is_before_start_date if planned_cfp_end_date.present? and start_date.present? and planned_cfp_end_date > start_date errors.add(:planned_cfp_end_date, :cannot_be_after_start_date) end end def start_date_is_before_end_date if start_date.present? and end_date.present? and start_date > end_date errors.add(:end_date, :cannot_be_before_start_date) end end class ConferenceVoteSummary include ActiveModel::Model attr_accessor :conference def number_of_ballots @number_of_ballots ||= remote_summary_data['number_of_ballots'] end def ranking @ranking ||= remote_summary_data['ranking'].map { |ranking_entry| EventRanking.new ranking_entry } end def save conference.transaction do conference.update number_of_ballots_cast: number_of_ballots ranking.all?(&:save) or raise ActiveRecord::Rollback conference.touch :vote_data_updated_at conference.save or raise ActiveRecord::Rollback end end private def conn @conn ||= Faraday.new(url: conference.vote_data_endpoint + '/summary.json', headers: {'Content-Type' => 'application/json'}) end def remote_summary_data @remote_summary_data ||= JSON.parse(conn.get do |request| request.body = {summary: {talk_ids: Conference.last.events.pluck(:id)}}.to_json end.body) end class EventRanking include ActiveModel::Model attr_accessor :talk_id, :votes, :place def save Event.find(talk_id).update(number_of_votes: votes, rank: place) end end end end