module Decidim::Coauthorable

This concern contains the logic related to collective or shared authorship.

Coauthorable shares nearly the same object interface as Authorable but with some differences.

All coauthors, including the initial author, will share the same permissions.

Public Instance Methods

add_coauthor(author, extra_attributes = {}) click to toggle source

Adds a new coauthor to the list of coauthors. The coauthorship is created with current object as coauthorable and `user` param as author. To set the user group use `extra_attributes` with the `user_group` key.

@param author: The new coauthor. @extra_attrs: Extra

# File lib/decidim/coauthorable.rb, line 140
def add_coauthor(author, extra_attributes = {})
  user_group = extra_attributes[:user_group]

  return if coauthorships.exists?(decidim_author_id: author.id, decidim_author_type: author.class.base_class.name) && user_group.blank?
  return if user_group && coauthorships.exists?(user_group: user_group)

  coauthorship_attributes = extra_attributes.merge(author: author)

  if persisted?
    coauthorships.create!(coauthorship_attributes)
  else
    coauthorships.build(coauthorship_attributes)
  end

  authors << author
end
authored_by?(author) click to toggle source

Checks whether the user is author of the given proposal, either directly authoring it or via a user group.

author - the author to check for authorship

# File lib/decidim/coauthorable.rb, line 93
def authored_by?(author)
  coauthorships.exists?(author: author)
end
authors() click to toggle source

Returns all the authors of a coauthorable.

We need to do it this ways since the authors are polymorphic, and we can't have a has_many through relation with polymorphic objects.

# File lib/decidim/coauthorable.rb, line 62
def authors
  return @authors if defined?(@authors)

  authors = coauthorships.pluck(:decidim_author_id, :decidim_author_type).each_with_object({}) do |(id, klass), all|
    all[klass] ||= []
    all[klass] << id
  end

  @authors = authors.flat_map do |klass, ids|
    klass.constantize.where(id: ids)
  end.compact.uniq
end
created_by?(author) click to toggle source

Checks whether the user is the creator of the given proposal

author - the author to check for authorship

# File lib/decidim/coauthorable.rb, line 119
def created_by?(author)
  author == creator_author
end
creator() click to toggle source

Syntactic sugar to access first coauthor as a Coauthorship.

# File lib/decidim/coauthorable.rb, line 112
def creator
  coauthorships.order(:created_at).first
end
creator_author() click to toggle source

Syntactic sugar to access first coauthor Author

# File lib/decidim/coauthorable.rb, line 124
def creator_author
  creator.try(:author)
end
creator_identity() click to toggle source

Syntactic sugar to access first identity whether it is a User or a UserGroup. @return The User od UserGroup that created this Coauthorable.

# File lib/decidim/coauthorable.rb, line 130
def creator_identity
  creator.try(:identity)
end
identities() click to toggle source

Returns the identities for the authors, whether they are user groups, users or others.

Returns an Array of User, UserGroups or any other entity capable object (such as Organization).

# File lib/decidim/coauthorable.rb, line 100
def identities
  coauthorships.includes(:author, :user_group).order(:created_at).collect(&:identity)
end
notifiable_identities() click to toggle source

Returns the identities that should be notified for a coauthorable.

# File lib/decidim/coauthorable.rb, line 77
def notifiable_identities
  @notifiable_identities ||= identities.flat_map do |identity|
    if identity.is_a?(Decidim::User)
      identity
    elsif identity.is_a?(Decidim::UserGroup)
      identity.managers
    elsif respond_to?(:component)
      component.participatory_space.admins
    end
  end.compact.uniq
end
reload(options = nil) click to toggle source

Overwrite default reload method to unset the instance variables so reloading works as expected.

Calls superclass method
# File lib/decidim/coauthorable.rb, line 52
def reload(options = nil)
  remove_instance_variable(:@authors) if defined?(@authors)
  remove_instance_variable(:@notifiable_identities) if defined?(@notifiable_identities)
  super(options)
end
user_identities() click to toggle source

Returns the identities for the authors, only if they are user groups or users.

Returns an Array of User and/or UserGroups.

# File lib/decidim/coauthorable.rb, line 107
def user_identities
  coauthorships.where(decidim_author_type: "Decidim::UserBaseEntity").order(:created_at).collect(&:identity)
end