Created
January 15, 2012 00:30
-
-
Save fdutey/1613585 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Formol | |
class Post < ActiveRecord::Base | |
#Security | |
attr_protected :topic_id, :user_id, :created_by_topic | |
#Virtual attributes | |
attr_accessor :created_by_topic, :quote_id, :register_user_as_subscriber | |
#Default values | |
default_value_for :created_by_topic, false | |
default_value_for :display_signature do |p| | |
p.user ? p.user.preference.use_signature : true | |
end | |
#Associations | |
belongs_to :topic, :touch => true, | |
:counter_cache => true | |
belongs_to :user, :class_name => Formol.config.user_class, | |
:counter_cache => :formol_posts_count | |
has_one :forum, :through => :topic | |
#Validations | |
validates :topic, :presence => true | |
validates :user, :presence => true | |
#Length is set with a minimum of 2 to allow posts with simple "ok" answer | |
#Length is set with a maximum of 50 000 because 50Kb is enough for a non | |
#binary forum | |
validates :content, :presence => true, | |
:length => { :in => 2..50_000, | |
:allow_blank => true } | |
validate :validates_topic_not_locked | |
#Normalization | |
normalize_attribute :content, :with => [:strip, :blank] | |
#Callbacks | |
after_initialize :feed_content_with_quote | |
after_save :register_author_as_subscriber | |
after_create :increment_forum_counter_cache, | |
:register_as_last_post_on_topic, | |
:register_as_last_post_on_forum | |
after_destroy :decrement_forum_counter_cache, | |
:unregister_as_last_post_on_topic, | |
:unregister_as_last_post_on_forum | |
#Scopes | |
class << self | |
# scope for ordering posts conveniently for listing views | |
# order by id (no order is random with mysql) | |
def ordered_for_listing | |
order('formol_posts.id ASC') | |
end | |
# scope to get posts conveniently prepared for listing | |
def ready_for_listing | |
ordered_for_listing.includes(:topic, { :user => :preference }) | |
end | |
# scope to get last five posts with reverse ordering | |
# usefull to have a little history when replying to a topic | |
def last_fives | |
order('formol_posts.id DESC').limit(5).includes(:user) | |
end | |
end | |
#Business methods | |
# Read accessor for 'register_user_as_subscriber' | |
def register_user_as_subscriber(force_recompute = false) | |
if @register_user_as_subscriber.nil? || force_recompute | |
@register_user_as_subscriber = compute_register_subscribing | |
end | |
@register_user_as_subscriber | |
end | |
private | |
# Convert 'register_user_as_subscriber' to boolean | |
def register_user_as_subscriber? | |
[true, '1', 'true'].include?(register_user_as_subscriber) | |
end | |
#Callback methods | |
# Registers author as subscriber if he's not already | |
def register_author_as_subscriber | |
if register_user_as_subscriber? | |
topic.register_subscriber(user) unless topic.subscriber?(user) | |
else | |
topic.unregister_subscriber(user) if topic.subscriber?(user) | |
end | |
end | |
# Validates topic is not locked | |
# If topic is locked, it will add an error on base (not on topic) | |
# This validation does not trigger on first post | |
def validates_topic_not_locked | |
errors.add(:base, :topic_locked) if topic.locked? && !created_by_topic | |
end | |
# Holds counter cache on Forum till AR does not support it on has_one | |
def increment_forum_counter_cache | |
Formol::Forum.increment_counter(:posts_count, forum.id) if forum.present? | |
end | |
# Holds counter cache on Forum till AR does not support it on has_one | |
def decrement_forum_counter_cache | |
Formol::Forum.decrement_counter(:posts_count, forum.id) if forum.present? | |
end | |
# Feed content with quote's content | |
# If you're trying to pass quote_id in a POST, your content will be wiped | |
# Too bad! | |
def feed_content_with_quote | |
return true if quote_id.blank? | |
q = topic.posts.find(quote_id) | |
formatter = Formol.config.formatter.new | |
# Extract and agnostize it | |
content_with_quote = "> **#{q.user.display_name} #{I18n.t('.wrote')}:**\n>\n" | |
content_with_quote << formatter.quote(q.content) | |
self.content = content_with_quote | |
self.content << "\n\n" #use '<<' to skip normalize_attribute | |
self.content | |
end | |
# Register current post being the last of its topic | |
def register_as_last_post_on_topic | |
topic.register_last_post(self) | |
end | |
# Unregister current post being the last of its topic | |
def unregister_as_last_post_on_topic | |
topic.unregister_last_post if topic.last_post == self | |
end | |
# Register current post being the last post of its forum | |
def register_as_last_post_on_forum | |
forum.register_last_post(self) | |
end | |
# Unregister current post being the last of its forum | |
def unregister_as_last_post_on_forum | |
forum.unregister_last_post if forum.last_post == self | |
end | |
# Computes 'register_user_as_subscriber | |
def compute_register_subscribing | |
if topic && user | |
topic.subscriber?(user) | |
else | |
false | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment