base/lib/social_stream/controllers/helpers.rb
module SocialStream
module Controllers
# Common methods added to ApplicationController
module Helpers
extend ActiveSupport::Concern
included do
helper_method :current_subject, :current_actor,
:profile_subject, :profile_subject?,
:profile_or_current_subject,
:profile_subject_is_current?
end
module ClassMethods
# Get the class relative to controller name
#
# Post #=> in PostsController
#
def model_class
self.name.sub(/Controller/, '').singularize.constantize
end
end
# Current subject represented by the user. Defaults to the own user
def current_subject
@current_subject ||=
current_subject_from_params ||
current_subject_from_session ||
current_user
end
# Set represented subject
def current_subject= instance
session[:subject_type] = instance.class.to_s
session[:subject_id] = instance.id
@current_subject = instance
end
def current_actor
current_subject.try(:actor)
end
# Returns the {SocialStream::Models::Subject subject} that is in the path, or
# nil if it is not provided
#
# # /users/demo/posts
# profile_subject #=> User demo
#
# # /groups/test/posts
# profile_subject #=> Group test
#
# # /posts
# profile_subject #=> nil
#
#
def profile_subject
@profile_subject ||= find_profile_subject
end
# Is {#profile_subject} provided?
def profile_subject?
profile_subject.present?
end
# Raise error if {#profile_subject} is not provided
def profile_subject!
profile_subject || warden.authenticate!
end
# Returns the {SocialStream::Models::Subject subject} that is in the path, or
# the {#current_subject} if some {User} is logged in.
#
# This method tries {#profile_subject} first and then {#current_subject}
def profile_or_current_subject
profile_subject || current_subject
end
# This method tries {#profile_or_current_subject} but tries to
# authenticate if the user is not logged in
def profile_or_current_subject!
profile_or_current_subject || warden.authenticate!
end
# A {User} must be logged in and is equal to {#profile_subject}
def profile_subject_is_current?
user_signed_in? && profile_subject == current_subject
end
# Override Cancan#current_ability method to use {#current_subject}
def current_ability
@current_ability ||=
::Ability.new(current_subject)
end
private
# Get represented subject from params[:s]
def current_subject_from_params
return unless params[:s].present?
subject = Actor.find_by_slug!(params[:s]).subject
unless subject.represented_by?(current_user)
raise CanCan::AccessDenied.new("Not authorized!", :represent, subject.name)
end
if subject != current_user
flash.now[:notice] ||= ""
flash.now[:notice] += t('representation.notice',
:subject => subject.name)
end
self.current_subject = subject
end
# Get represented subject from session
def current_subject_from_session
return unless session[:subject_type].present? && session[:subject_id].present?
session[:subject_type].constantize.find session[:subject_id]
end
def find_profile_subject
SocialStream.profile_subject_keys.each do |type|
id = params["#{ type }_id"]
next if id.blank?
subject_class =
begin
type.to_s.classify.constantize
rescue NameError => e
# Try with namespace
ns = params[:controller].split('/')
ns.pop
if ns.blank?
raise e
end
ns.push(type)
ns.join('/').classify.constantize
end
return subject_class.find_by_slug! id
end
nil
end
end
end
end