Setup basic Revision History page

Sets up paper_trail tracking in important models

and add conference_id to versions for storing conference_id
of conference related objects  as metadata.This will help in querying
for versions related to conferences.

Fix issues with factories & event types initialization.Import paper_trail testing helpers
Fix bug: Creating an event creates a useless version with event update

Add revert and view changes features to revision history
This commit is contained in:
Nishanth Vijayan 2016-05-24 23:54:46 +05:30
parent 60877e9593
commit a45e537bac
49 changed files with 760 additions and 26 deletions

View file

@ -114,6 +114,14 @@ class Ability
# for admins
can :manage, :all if user.is_admin
cannot :revert_object, PaperTrail::Version do |version|
(version.event == 'create' && %w(Conference User Event).include?(version.item_type))
end
cannot :revert_attribute, PaperTrail::Version do |version|
version.event != 'update' || version.item.nil?
end
cannot :destroy, Program
# Do not delete venue, when there are rooms being used
cannot :destroy, Venue do |venue|
@ -168,6 +176,10 @@ class Ability
can [:edit, :update, :toggle_user], Role do |role|
role.resource_type == 'Conference' && (conf_ids_for_organizer.include? role.resource_id)
end
can [:index, :revert_object, :revert_attribute], PaperTrail::Version do |version|
version.item_type == 'User' || (conf_ids_for_organizer.include? version.conference_id)
end
end
def signed_in_with_cfp_role(user)

View file

@ -4,6 +4,8 @@ class Campaign < ActiveRecord::Base
has_many :targets, dependent: :nullify
belongs_to :conference
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
##
# Returns the utm parameters formatted as url.
#

View file

@ -1,6 +1,7 @@
# cannot delete program if there are events submitted
class Cfp < ActiveRecord::Base
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
belongs_to :program
validates :program_id, presence: true
@ -68,4 +69,8 @@ class Cfp < ActiveRecord::Base
errors.
add(:start_date, "can't be after the end date") if start_date && end_date && start_date > end_date
end
def conference_id
program.conference_id
end
end

View file

@ -13,6 +13,8 @@ class Comment < ActiveRecord::Base
# NOTE: Comments belong to a user
belongs_to :user
has_paper_trail on: [:create, :destroy], meta: { conference_id: :conference_id }
# Helper class method that allows you to build a comment
# by passing a commentable object, a user_id, and comment text
# example in readme
@ -58,4 +60,8 @@ class Comment < ActiveRecord::Base
def send_notification
EventCommentMailJob.perform_later(self)
end
def conference_id
commentable.program.conference_id
end
end

View file

@ -3,6 +3,8 @@ class Commercial < ActiveRecord::Base
belongs_to :commercialable, polymorphic: true
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
validates :url, presence: true
validates :url, format: URI::regexp(%w(http https))
@ -41,4 +43,12 @@ class Commercial < ActiveRecord::Base
speakerdeck
)
end
def conference_id
case commercialable_type
when 'Conference' then commercialable_id
when 'Event' then Event.find(commercialable_id).program.conference_id
when 'Venue' then Venue.find(commercialable_id).conference_id
end
end
end

View file

@ -9,7 +9,7 @@ class Conference < ActiveRecord::Base
default_scope { order('start_date DESC') }
has_paper_trail
has_paper_trail ignore: [:updated_at, :guid, :revision, :events_per_week], meta: { conference_id: :id }
has_and_belongs_to_many :questions

View file

@ -1,4 +1,6 @@
class Contact < ActiveRecord::Base
has_paper_trail on: [:update], ignore: [:updated_at], meta: { conference_id: :conference_id }
belongs_to :conference
validates :conference, presence: true

View file

@ -2,7 +2,10 @@ class DifficultyLevel < ActiveRecord::Base
belongs_to :program
has_many :events, dependent: :nullify
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
validates :title, presence: true
validates :color, format: /\A#[0-9A-F]{6}\z/
before_validation :capitalize_color
@ -12,4 +15,8 @@ class DifficultyLevel < ActiveRecord::Base
def capitalize_color
self.color = color.upcase if color.present?
end
def conference_id
program.conference_id
end
end

View file

@ -1,6 +1,8 @@
class EmailSettings < ActiveRecord::Base
belongs_to :conference
has_paper_trail on: [:update], ignore: [:updated_at], meta: { conference_id: :conference_id }
def get_values(conference, user, event = nil)
h = {
'email' => user.email,

View file

@ -1,6 +1,6 @@
class Event < ActiveRecord::Base
include ActiveRecord::Transitions
has_paper_trail
has_paper_trail on: [:create, :update], ignore: [:updated_at, :guid, :week], meta: { conference_id: :conference_id }
acts_as_commentable
@ -280,7 +280,9 @@ class Event < ActiveRecord::Base
def set_week
self.week = created_at.strftime('%W')
save!
self.without_versioning do
self.save!
end
end
def before_end_of_conference
@ -288,4 +290,8 @@ class Event < ActiveRecord::Base
add(:created_at, "can't be after the conference end date!") if program.conference && program.conference.end_date &&
(Date.today > program.conference.end_date)
end
def conference_id
program.conference_id
end
end

View file

@ -2,6 +2,8 @@ class EventType < ActiveRecord::Base
belongs_to :program
has_many :events, dependent: :restrict_with_error
has_paper_trail meta: { conference_id: :conference_id }
validates :title, presence: true
validates :length, numericality: {greater_than: 0}
validates :minimum_abstract_length, presence: true
@ -28,4 +30,8 @@ class EventType < ActiveRecord::Base
def capitalize_color
self.color = color.upcase if color.present?
end
def conference_id
program.conference_id
end
end

View file

@ -4,9 +4,17 @@ class EventsRegistration < ActiveRecord::Base
has_one :user, through: :registration
has_paper_trail meta: { conference_id: :conference_id }
delegate :name, to: :registration
delegate :email, to: :registration
validates :event, :registration, presence: true
validates :event, uniqueness: { scope: :registration }
private
def conference_id
registration.conference_id
end
end

View file

@ -1,6 +1,8 @@
class Lodging < ActiveRecord::Base
belongs_to :conference
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
validates :name, presence: true
mount_uploader :picture, PictureUploader, mount_on: :photo_file_name

View file

@ -1,6 +1,8 @@
# cannot delete program if there are events submitted
class Program < ActiveRecord::Base
has_paper_trail on: [:update], ignore: [:updated_at], meta: { conference_id: :conference_id }
belongs_to :conference
has_one :cfp, dependent: :destroy
@ -53,8 +55,8 @@ class Program < ActiveRecord::Base
validate :voting_start_date_before_end_date
validate :voting_dates_exist
before_create :create_event_types
before_create :create_difficulty_levels
after_create :create_event_types
after_create :create_difficulty_levels
validate :check_languages_format
# Returns all event_schedules for the selected schedule ordered by start_time
@ -157,12 +159,12 @@ class Program < ActiveRecord::Base
# Creates default EventTypes for this Conference. Used as before_create.
#
def create_event_types
event_types << EventType.create(title: 'Talk', length: 30, color: '#FF0000', description: 'Presentation in lecture format',
minimum_abstract_length: 0,
maximum_abstract_length: 500)
event_types << EventType.create(title: 'Workshop', length: 60, color: '#0000FF', description: 'Interactive hands-on practice',
minimum_abstract_length: 0,
maximum_abstract_length: 500)
EventType.create(title: 'Talk', length: 30, color: '#FF0000', description: 'Presentation in lecture format',
minimum_abstract_length: 0,
maximum_abstract_length: 500, program_id: self.id)
EventType.create(title: 'Workshop', length: 60, color: '#0000FF', description: 'Interactive hands-on practice',
minimum_abstract_length: 0,
maximum_abstract_length: 500, program_id: self.id)
true
end
@ -170,15 +172,15 @@ class Program < ActiveRecord::Base
# Creates default DifficultyLevels for this Conference. Used as before_create.
#
def create_difficulty_levels
difficulty_levels << DifficultyLevel.create(title: 'Easy',
description: 'Events are understandable for everyone without knowledge of the topic.',
color: '#70EF69')
difficulty_levels << DifficultyLevel.create(title: 'Medium',
description: 'Events require a basic understanding of the topic.',
color: '#EEEF69')
difficulty_levels << DifficultyLevel.create(title: 'Hard',
description: 'Events require expert knowledge of the topic.',
color: '#EF6E69')
DifficultyLevel.create(title: 'Easy',
description: 'Events are understandable for everyone without knowledge of the topic.',
color: '#70EF69', program_id: self.id)
DifficultyLevel.create(title: 'Medium',
description: 'Events require a basic understanding of the topic.',
color: '#EEEF69', program_id: self.id)
DifficultyLevel.create(title: 'Hard',
description: 'Events require expert knowledge of the topic.',
color: '#EF6E69', program_id: self.id)
true
end

View file

@ -7,7 +7,9 @@ class Registration < ActiveRecord::Base
has_and_belongs_to_many :vchoices
has_many :events_registrations
has_many :events, through: :events_registrations
has_many :events, through: :events_registrations, dependent: :destroy
has_paper_trail ignore: [:updated_at, :week], meta: { conference_id: :conference_id }
accepts_nested_attributes_for :user
accepts_nested_attributes_for :qanswers
@ -75,7 +77,9 @@ class Registration < ActiveRecord::Base
def set_week
self.week = created_at.strftime('%W')
save!
without_versioning do
save!
end
end
def registration_limit_not_exceed

View file

@ -1,6 +1,8 @@
class RegistrationPeriod < ActiveRecord::Base
belongs_to :conference
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
validates :start_date, :end_date, presence: true
validate :before_end_of_conference
validate :start_date_before_end_date

View file

@ -1,6 +1,10 @@
class Role < ActiveRecord::Base
belongs_to :resource, polymorphic: true
has_and_belongs_to_many :users, join_table: :users_roles
has_many :users_roles
has_many :users, through: :users_roles
has_paper_trail on: [:update], only: [:name, :description], meta: { conference_id: :resource_id }
before_destroy :cancel
scopify

View file

@ -2,6 +2,8 @@ class Room < ActiveRecord::Base
belongs_to :venue
has_many :event_schedules, dependent: :nullify
has_paper_trail ignore: [:guid], meta: { conference_id: :conference_id }
before_create :generate_guid
validates :name, :venue_id, presence: true
@ -14,4 +16,8 @@ class Room < ActiveRecord::Base
guid = SecureRandom.urlsafe_base64
self.guid = guid
end
def conference_id
venue.conference_id
end
end

View file

@ -1,3 +1,5 @@
class Splashpage < ActiveRecord::Base
belongs_to :conference
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
end

View file

@ -2,6 +2,8 @@ class Sponsor < ActiveRecord::Base
belongs_to :sponsorship_level
belongs_to :conference
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
mount_uploader :picture, PictureUploader, mount_on: :logo_file_name
validates_presence_of :name, :website_url, :sponsorship_level

View file

@ -3,4 +3,6 @@ class SponsorshipLevel < ActiveRecord::Base
belongs_to :conference
acts_as_list scope: :conference
has_many :sponsors
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
end

View file

@ -3,5 +3,7 @@ class Subscription < ActiveRecord::Base
belongs_to :conference
belongs_to :user
has_paper_trail on: [:create, :destroy], ignore: [:updated_at], meta: { conference_id: :conference_id }
validates_uniqueness_of :user_id, scope: :conference_id, message: 'already subscribed!'
end

View file

@ -3,6 +3,8 @@ class Target < ActiveRecord::Base
default_scope { order('due_date ASC') }
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
def self.units
{
registrations: 'Registration',

View file

@ -3,6 +3,8 @@ class Ticket < ActiveRecord::Base
has_many :ticket_purchases, dependent: :destroy
has_many :buyers, -> { distinct }, through: :ticket_purchases, source: :user
has_paper_trail meta: { conference_id: :conference_id }
monetize :price_cents, with_model_currency: :price_currency
# This validation is for the sake of simplicity.

View file

@ -2,6 +2,8 @@ class Track < ActiveRecord::Base
belongs_to :program
has_many :events, dependent: :nullify
has_paper_trail only: [:name, :description, :color], meta: { conference_id: :conference_id }
before_create :generate_guid
validates :name, presence: true
validates :color, format: /\A#[0-9A-F]{6}\z/
@ -21,4 +23,8 @@ class Track < ActiveRecord::Base
def capitalize_color
self.color = color.upcase if color.present?
end
def conference_id
program.conference_id
end
end

View file

@ -6,6 +6,12 @@ end
class User < ActiveRecord::Base
rolify
has_many :users_roles
has_many :roles, through: :users_roles, dependent: :destroy
has_paper_trail on: [:create, :update], ignore: [:sign_in_count, :remember_created_at, :current_sign_in_at, :last_sign_in_at, :current_sign_in_ip, :last_sign_in_ip, :unconfirmed_email,
:avatar_content_type, :avatar_file_size, :avatar_updated_at, :updated_at, :confirmation_sent_at, :confirmation_token, :reset_password_token]
include Gravtastic
gravtastic size: 32
@ -72,7 +78,7 @@ class User < ActiveRecord::Base
end
def name
self[:name] || username
self[:name].blank? ? username : self[:name]
end
##

12
app/models/users_role.rb Normal file
View file

@ -0,0 +1,12 @@
class UsersRole < ActiveRecord::Base
belongs_to :role
belongs_to :user
has_paper_trail on: [:create, :destroy], meta: { conference_id: :conference_id }
private
def conference_id
role.resource_id
end
end

View file

@ -4,6 +4,8 @@ class Venue < ActiveRecord::Base
has_many :rooms, dependent: :destroy
before_create :generate_guid
has_paper_trail ignore: [:updated_at, :guid], meta: { conference_id: :conference_id }
accepts_nested_attributes_for :commercial, allow_destroy: true
validates :name, :street, :city, :country, presence: true

View file

@ -1,5 +1,14 @@
class Vote < ActiveRecord::Base
belongs_to :user
belongs_to :event
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
delegate :name, to: :user
private
def conference_id
event.program.conference_id
end
end