Module: Joinable::ActsAsJoinable::ClassMethods

Includes:
Joinable::ActsAsPermissable::ClassMethods
Defined in:
lib/joinable/acts_as_joinable.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Joinable::ActsAsPermissable::ClassMethods

#find_with_privacy, #permission_sql_condition, #with_permission

Class Method Details

.extended(base) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/joinable/acts_as_joinable.rb', line 47

def self.extended(base)
  base.class_eval do
    cattr_accessor :permissions, :component_permissions_hash

    has_many :membership_invitations,   :as => :joinable, :dependent => :destroy, :before_add => :add_initiator
    has_many :membership_requests,      :as => :joinable, :dependent => :destroy
    has_many :memberships,              lambda { order :id }, :as => :joinable, :dependent => :destroy, :before_remove => :add_initiator

    has_many :invitees,                 :class_name => "User", :through => :membership_invitations, :source => :user
    has_many :requestees,               :class_name => "User", :through => :membership_requests, :source => :user
    has_many :members,                  :class_name => "User", :through => :memberships, :source => :user

    has_many :permission_links,         :as => :joinable, :dependent => :destroy
    has_one :default_permission_set,    :as => :joinable, :dependent => :destroy
            
    scope :with_member,                 lambda {|user| joins(:memberships).where(:memberships => {:user_id => user}).order("memberships.created_at DESC") }

    accepts_nested_attributes_for :default_permission_set
    accepts_nested_attributes_for :membership_invitations, :allow_destroy => true
    accepts_nested_attributes_for :memberships, :allow_destroy => true, :reject_if => proc { |attributes| attributes['locked'] == 'true' }

    after_create :add_owner_membership
  end
end

Instance Method Details

#collaborator_permissionsObject



92
93
94
# File 'lib/joinable/acts_as_joinable.rb', line 92

def collaborator_permissions
  permissions - [:manage, :own]
end

#collaborator_permissions_stringObject

Member can view everything and modify everything except members



88
89
90
# File 'lib/joinable/acts_as_joinable.rb', line 88

def collaborator_permissions_string
  collaborator_permissions.join(" ")
end

#manager_permissions_stringObject

Member can view everything, modify everything, and manage membership



97
98
99
# File 'lib/joinable/acts_as_joinable.rb', line 97

def manager_permissions_string
  (permissions - [:own]).join(" ")
end

#owner_permissions_stringObject

Member started the joinable



102
103
104
# File 'lib/joinable/acts_as_joinable.rb', line 102

def owner_permissions_string
  permissions_string
end

#permissions_stringObject



72
73
74
# File 'lib/joinable/acts_as_joinable.rb', line 72

def permissions_string
  permissions.join(" ")
end

#viewer_permissionsObject



83
84
85
# File 'lib/joinable/acts_as_joinable.rb', line 83

def viewer_permissions
  permissions.select { |permission| permission == :find || permission.to_s.starts_with?("view") }
end

#viewer_permissions_stringObject

Simple Permission Strings - Permission strings for four basic levels of permissions - viewer, collaborator, manager, owner

Member can view everything but modify nothing



79
80
81
# File 'lib/joinable/acts_as_joinable.rb', line 79

def viewer_permissions_string
  viewer_permissions.join(" ")
end

#with_permission_sql(user, permission, options = {}) ⇒ Object

Returns the SQL necessary to find all joinables for which the user has a membership with a specific permission.

Permissions which require special handling:

  • find - In addition to memberships, invitations and default permission sets are checked for the permission. This is because

    a joinable should be able to be found once an invitation has been extended or if it is findable by default. (even if the user isn't a member of it).
    
  • view_* - This is a class of permissions that start with the word ‘view’. When determining if a user can view any aspect of a joinable, we also check

    if the project is open.
    
  • join - This is a faux permission. A user has permission to join a joinable if they have an invitation to view it or if it is viewable by default.

  • collaborate - This is a faux permission. A user has permission to collaborate if they have any additional permissions above the standard viewer permissions.



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/joinable/acts_as_joinable.rb', line 122

def with_permission_sql(user, permission, options = {})
  permission = permission.to_sym

  case user
  when String
    user_id = user
  when
    user_id = user.id
  end

  joinable_id = options[:id_column] || "#{table_name}.id"

  if permission == :find
    "#{membership_permission_exists_sql(user_id, joinable_id, 'find')} OR #{membership_invitation_permission_exists_sql(user_id, joinable_id, 'find')} OR #{default_permission_set_permission_exists_sql(joinable_id, 'find')}"
  elsif permission.to_s.starts_with?('view')
    "#{membership_permission_exists_sql(user_id, joinable_id, permission)} OR #{default_permission_set_permission_exists_sql(joinable_id, permission)}"
  elsif permission == :join
    "#{membership_invitation_permission_exists_sql(user_id, joinable_id, 'view')} OR #{default_permission_set_permission_exists_sql(joinable_id, 'view')}"
  elsif permission.to_s.starts_with?('join_and_')
    default_permission_set_permission_exists_sql(joinable_id, permission.to_s.gsub('join_and_', ''))
  elsif permission == :collaborate
    "EXISTS (SELECT id FROM memberships WHERE memberships.joinable_type = '#{self.name}' AND memberships.joinable_id = #{joinable_id} AND memberships.user_id = #{user_id} AND memberships.permissions && '{#{(collaborator_permissions - viewer_permissions).join(",")}}')"
  else
    membership_permission_exists_sql(user_id, joinable_id, permission)
  end
end