Skip to content

Instantly share code, notes, and snippets.

@msaspence
Created April 5, 2013 07:55
class Action < ActiveRecord::Base
include OpenGraph
include Activity
default_scope where(pending: false, archived: false)
scope :pending, where(pending: true, archived: false)
attr_accessible :title, :summary, :description, :user_id, :image, :fund_ceiling, :participation_target_count, :campaign_id, :cause_id, :featured, :poll_options, :poll_options_attributes, :pending, :archived, as: :admin
attr_accessible :title, :summary, :description, :image, :poll_options_attributes
mount_uploader :image, ActionImageUploader
validates :title, presence: true
validates :summary, format: { with: /\A[^\r\n]*\z/, message: "can not have new lines" }, allow_nil: true, allow_blank: true
validates :description, presence: true
if defined?(PatientsCreateAdmin) && Rails.application.is_a?(PatientsCreateAdmin)
validates :campaign, presence: true
end
belongs_to :user
belongs_to :campaign, inverse_of: :actions, touch: true, counter_cache: true
belongs_to :cause
has_many :responses, order: "\"created_at\" > '#{1.hour.ago}' DESC,\"up_votes_count\" DESC, \"created_at\" DESC"
has_many :responders, through: :responses, uniq: true, source: :user
has_many :views, class_name: '::PublicActivity::Activity', conditions: { key: 'action.view', trackable_type: 'Action' }, foreign_key: :trackable_id
has_many :poll_options, order: :weight
has_many :poll_votes, order: '"created_at" DESC'
has_many :poll_voters, class_name: 'User', through: :poll_votes, source: :user
has_many :response_comments, through: :responses, source: :comments
has_many :response_commenters, through: :response_comments, uniq: true, source: :user
has_many :response_up_votes, through: :responses, source: :up_votes
has_many :response_up_voters, through: :response_up_votes, source: :user
has_many :comment_up_votes, through: :response_comments, source: :up_votes
has_many :comment_up_voters, through: :comment_up_votes, source: :user
has_many :facebook_requests
accepts_nested_attributes_for :poll_options, allow_destroy: true, reject_if: :all_blank
scope :featured, where('featured')
after_update :update_campaing_actions_count
def update_campaing_actions_count
Campaign.decrement_counter(:actions_count, self.campaign_id_was)
Campaign.increment_counter(:actions_count, self.campaign_id)
end
after_update :touch_old_campaign
def touch_old_campaign
Campaign.find(campaign_id_was).touch unless campaign_id == campaign_id_was
end
after_save :email_author_if_first_published
def email_author_if_first_published
if pending_was == true && pending == false
self.create_activity key: 'action.publish'
delay.send_action_published_email
end
end
def send_action_published_email
ActionAuthorMailer.action_published(self, self.user).deliver
end
def participants
(responders + poll_voters + response_commenters + response_up_voters + comment_up_voters).uniq(&:id)
end
def participant_ids
participants.map(&:id)
end
def has_poll_options?
poll_options.size > 0
end
alias :has_poll_options :has_poll_options?
def has_poll_option? poll_option_id
poll_option_id = poll_option_id.id if poll_option_id.is_a?(PollOption)
poll_option_ids.include? poll_option_id
end
alias :has_poll_option :has_poll_option?
def poll_options_or_agree_disagree
if has_poll_options?
return poll_options + [ PollOption.something_option_for(self) ]
else
return [
PollOption.agree_option_for(self),
PollOption.disagree_option_for(self)
]
end
end
def total_raised
return 0 unless sponsored?
raised = participation_value * participation_count
if raised > fund_ceiling
fund_ceiling
else
raised
end
end
def fund_ceiling_reached?
participation_count >= (participation_target_count || 0)
end
alias :fund_ceiling_reached :fund_ceiling_reached?
def participation_value
return 0 unless sponsored?
fund_ceiling / participation_target_count
end
def percentage_funded
(total_raised.to_f/fund_ceiling.to_f)*100
end
def next_target
[100,200,500,1000,2000,5000,10000,20000,100000,1000000].each do |x|
return x if (participation_count || 0) < x
end
1000000
end
def percentage_completed
v = (participation_count.to_f/participation_target_count.to_f)*100
v > 100.0 ? 100.0 : v
end
def max_poll_option_votes_count
poll_options_or_agree_disagree.map(&:poll_votes_count).max
end
def url
open_graph_url "/actions/#{id}"
end
def mixpanel_data_points
{
campaign_id: campaign_id,
cause_id: cause_id
}
end
def sponsored?
fund_ceiling && fund_ceiling > 0
end
alias :sponsored :sponsored?
def increment_visitors_count user_id
self.increment! :visitors_count unless has_been_viewed_by? user_id
campaign.increment! :visitors_count unless !campaign || campaign.has_or_any_action_has_been_viewed_by?(user_id)
end
def has_been_viewed_by? user_id
PublicActivity::Activity.where(owner_id: user_id.to_i, key: 'action.view', trackable_id: id, trackable_type: 'Action').count > 0
end
alias :has_been_viewed_by :has_been_viewed_by?
def open_graph_type
'campaign_action'
end
def facebook_invite_message
"Please help me raise awareness on PatientsCreate. It'll take you 5 seconds and could create genuine change. Thanks"
end
def participation_target_count
value = read_attribute(:participation_target_count)
if (value && value > 0)
value
else
sponsored ? 50 : next_target
end
end
def publish
self.pending = false
end
def publish!
publish
save
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment