Module: Joinable::ActsAsJoinableComponent::InstanceMethods

Includes:
Joinable::ActsAsPermissable::InstanceMethods
Defined in:
lib/joinable/acts_as_joinable_component.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Joinable::ActsAsPermissable::InstanceMethods

#acts_like_permissable?, #who_can?

Instance Attribute Details

#view_permissionObject



190
191
192
193
194
195
196
# File 'lib/joinable/acts_as_joinable_component.rb', line 190

def view_permission
  klass_view_permission = self.class.view_permission
  klass_view_permission = klass_view_permission.call(self) if klass_view_permission.respond_to?(:call)

  # Allow view_permission to be set at the instance level
  return @view_permission || klass_view_permission
end

Instance Method Details

#acts_like_joinable_component?Boolean

Returns:

  • (Boolean)


124
125
126
# File 'lib/joinable/acts_as_joinable_component.rb', line 124

def acts_like_joinable_component?
  true
end

#check_permission(user, permission) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/joinable/acts_as_joinable_component.rb', line 140

def check_permission(user, permission)
  # You can't ask to join joinable_components so the find permission is actually the view permission
  permission = :view if permission == :find
  
  if new_record?
    if joinable.acts_like?(:joinable)
      permission = recurse_to_inherit_custom_view_permission if permission == :view
      joinable.check_permission(user, permission)
    else
      # The component isn't contained by a joinable so it is public.
      true
    end
  else
    self.class.with_permission(user, permission).exists?(id)
  end
end

Creates a link to the joinable that this component is associated with, if there is one.



218
219
220
# File 'lib/joinable/acts_as_joinable_component.rb', line 218

def find_joinable_and_create_permission_link
  self.create_permission_link(:joinable => joinable, :component_view_permission => recurse_to_inherit_custom_view_permission) if joinable.acts_like?(:joinable)
end

#inherited_view_permissionObject

inherited_view_permission is calculated by ascending up the chain of joinable components while view permission only takes into account the current joinable component. inherited_view_permission is for external use while view_permission should only be used internally.



186
187
188
# File 'lib/joinable/acts_as_joinable_component.rb', line 186

def inherited_view_permission
  permission_link.try(:component_view_permission)
end

#joinableObject

Returns the object that we should inherit permissions from

Recurses until the target is reached, if we reach a target that does not act as a joinable, call method again if it is a joinable component, else fall out as the chain has no valid endpoint (eg. feed -> discussion -> item)



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/joinable/acts_as_joinable_component.rb', line 162

def joinable
  if permission_link.present?
    permission_link.joinable
  else
    parent = next_link
    
    # Our target is now joinable therefore our target is at the end (eg. feed -> discussion -> [project])
    if parent && parent.acts_like?(:joinable)
      return parent

    # Our target is a joinable_component therefore our target somewhere between the beginning and the end (eg. feed -> [discussion] -> ??? -> project)
    elsif parent && parent.acts_like?(:joinable_component)
      return parent.joinable

    # We've fallen out because there was either no target or the target was not joinable or a joinable_component
    else
      return parent
    end
  end
end

#recurse_to_inherit_custom_view_permissionObject

Recurse up the tree to see if any of the intervening joinable_components have a customized view permission In that case, inherit that customized view permission. This allows searches of the form Feed.with_permission(:view) where feeds belong to joinable_components with custom view permissions. The query will then be able to return only the feeds which belong to joinable components that are viewable by the user



204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/joinable/acts_as_joinable_component.rb', line 204

def recurse_to_inherit_custom_view_permission
  parent = next_link

  # If we've reached the last component in the chain or if this component provides a view permission
  if parent.acts_like?(:joinable) || self.view_permission
    return self.view_permission || :view
  elsif parent.acts_like?(:joinable_component)
    return parent.recurse_to_inherit_custom_view_permission
  else
    return nil
  end
end

#who_will_be_able_to_view?Boolean

Used by unsaved joinable_components to return a list of users who will be able to view the component once it is saved. Useful for outputting information to the user while they are creating a new component.

Returns:

  • (Boolean)


132
133
134
135
136
137
138
# File 'lib/joinable/acts_as_joinable_component.rb', line 132

def who_will_be_able_to_view?
  User.find_by_sql("SELECT users.* 
                    FROM users JOIN memberships ON users.id = memberships.user_id 
                    WHERE memberships.joinable_type = '#{joinable.class.to_s}' 
                    AND memberships.joinable_id = #{joinable.id} 
                    AND #{self.class.permission_sql_condition('memberships.permissions', recurse_to_inherit_custom_view_permission)}")
end