Class: Decidim::Initiative
- Inherits:
-
ApplicationRecord
- Object
- ApplicationRecord
- Decidim::Initiative
- Includes:
- ActiveModel::Dirty, Authorable, Comments::Commentable, DownloadYourData, FilterableResource, Followable, HasArea, HasAttachmentCollections, HasAttachments, HasReference, HasResourcePermission, Decidim::Initiatives::HasArea, Decidim::Initiatives::InitiativeSlug, Loggable, Participable, Publicable, Randomable, Reportable, Resourceable, ScopableParticipatorySpace, Searchable, ShareableWithToken, Traceable, TranslatableResource
- Defined in:
- app/models/decidim/initiative.rb
Overview
The data store for a Initiative in the Decidim::Initiatives component.
Class Method Summary collapse
- .export_serializer ⇒ Object
- .log_presenter_class_for(_log) ⇒ Object
- .ransack(params = {}, options = {}) ⇒ Object
- .ransackable_associations(_auth_object = nil) ⇒ Object
- .ransackable_attributes(auth_object = nil) ⇒ Object
- .ransackable_scopes(_auth_object = nil) ⇒ Object
Instance Method Summary collapse
- #accepts_offline_votes? ⇒ Boolean
- #accepts_online_unvotes? ⇒ Boolean
- #accepts_online_votes? ⇒ Boolean
-
#allow_resource_permissions? ⇒ Boolean
Public: Overrides the ‘allow_resource_permissions?` Resourceable concern method.
-
#answered? ⇒ Boolean
Public: Checks if the organization has given an answer for the initiative.
-
#author_name ⇒ Object
Public: Returns the author name.
- #author_users ⇒ Object
-
#banner_image ⇒ Object
Public: Overrides participatory space’s banner image with the banner image defined for the initiative type.
-
#commentable? ⇒ Boolean
Public: Whether the object’s comments are visible or not.
-
#comments_have_alignment? ⇒ Boolean
Public: Overrides the ‘comments_have_alignment?` Commentable concern method.
-
#comments_have_votes? ⇒ Boolean
Public: Overrides the ‘comments_have_votes?` Commentable concern method.
- #component ⇒ Object
-
#created_by_individual? ⇒ Boolean
Public: Check if an initiative has been created by an individual person.
- #enough_committee_members? ⇒ Boolean
-
#has_authorship?(user) ⇒ Boolean
Public: Checks if user is the author or is part of the promotal committee of the initiative.
-
#has_signature_interval_defined? ⇒ Boolean
Public: Returns whether the signature interval is already defined or not.
-
#hashtag ⇒ Object
Public: Returns the hashtag for the initiative.
- #minimum_committee_members ⇒ Object
- #missing_committee_members ⇒ Object
- #offline_votes_count ⇒ Object
- #offline_votes_count_for(scope) ⇒ Object
-
#online_votes_count ⇒ Object
Public: Calculates all the votes across all the scopes.
- #online_votes_count_for(scope) ⇒ Object
-
#percentage ⇒ Object
Public: Returns the percentage of required supports reached.
-
#publish! ⇒ Object
Public: Publishes this initiative.
-
#reported_attributes ⇒ Object
Public: Overrides the ‘reported_attributes` Reportable concern method.
-
#reported_content_url ⇒ Object
Public: Overrides the ‘reported_content_url` Reportable concern method.
-
#scopes_enabled ⇒ Object
Public: Overrides scopes enabled attribute value.
-
#scopes_enabled? ⇒ Boolean
Public: Overrides scopes enabled flag available in other models like participatory space or assemblies.
- #set_offline_votes_total ⇒ Object
- #shareable_url(share_token) ⇒ Object
-
#slug ⇒ Object
Public: Overrides slug attribute from participatory processes.
-
#supports_count ⇒ Object
Public: Calculates the number of total current supports.
-
#supports_count_for(scope) ⇒ Object
Public: Calculates the number of current supports for a scope.
-
#supports_goal_reached? ⇒ Boolean
Public: Whether the supports required objective has been reached.
-
#supports_goal_reached_for?(scope) ⇒ Boolean
Public: Whether the supports required objective has been reached for a scope.
-
#supports_required_for(scope) ⇒ Object
Public: Calculates the number of supports required to accept the initiative for a scope.
- #to_param ⇒ Object
-
#unpublish! ⇒ Object
Public: Unpublishes this initiative.
- #update_online_votes_counters ⇒ Object
- #user_allowed_to_comment?(user) ⇒ Boolean
-
#user_role_config_for(_user, _role_name) ⇒ Object
Public: Returns an empty object.
-
#validate_sms_code_on_votes? ⇒ Boolean
Public: Checks if the type the initiative belongs to enables SMS code verification step.
-
#votable_initiative_type_scopes ⇒ Object
Public: Finds all the InitiativeTypeScopes that are eligible to be voted by a user.
-
#voted_by?(user) ⇒ Boolean
Public: Check if the user has voted the question.
- #votes_enabled? ⇒ Boolean
Methods included from Decidim::Initiatives::InitiativeSlug
Class Method Details
.export_serializer ⇒ Object
161 162 163 |
# File 'app/models/decidim/initiative.rb', line 161 def self.export_serializer Decidim::Initiatives::DownloadYourDataInitiativeSerializer end |
.log_presenter_class_for(_log) ⇒ Object
165 166 167 |
# File 'app/models/decidim/initiative.rb', line 165 def self.log_presenter_class_for(_log) Decidim::Initiatives::AdminLog::InitiativePresenter end |
.ransack(params = {}, options = {}) ⇒ Object
481 482 483 |
# File 'app/models/decidim/initiative.rb', line 481 def self.ransack(params = {}, = {}) Initiatives::InitiativeSearch.new(self, params, ) end |
.ransackable_associations(_auth_object = nil) ⇒ Object
177 178 179 |
# File 'app/models/decidim/initiative.rb', line 177 def self.ransackable_associations(_auth_object = nil) %w(area scope taxonomies) end |
.ransackable_attributes(auth_object = nil) ⇒ Object
169 170 171 172 173 174 175 |
# File 'app/models/decidim/initiative.rb', line 169 def self.ransackable_attributes(auth_object = nil) base = %w(search_text title description id id_string supports_count author_name author_nickname) return base unless auth_object&.admin? base + %w(published_at state decidim_area_id type_id) end |
.ransackable_scopes(_auth_object = nil) ⇒ Object
181 182 183 |
# File 'app/models/decidim/initiative.rb', line 181 def self.ransackable_scopes(_auth_object = nil) [:with_any_state, :with_any_type, :with_any_scope, :with_any_area] end |
Instance Method Details
#accepts_offline_votes? ⇒ Boolean
424 425 426 |
# File 'app/models/decidim/initiative.rb', line 424 def accepts_offline_votes? published? && (offline_signature_type? || any_signature_type?) end |
#accepts_online_unvotes? ⇒ Boolean
432 433 434 |
# File 'app/models/decidim/initiative.rb', line 432 def accepts_online_unvotes? accepts_online_votes? && type.undo_online_signatures_enabled? end |
#accepts_online_votes? ⇒ Boolean
428 429 430 |
# File 'app/models/decidim/initiative.rb', line 428 def accepts_online_votes? votes_enabled? && (online_signature_type? || any_signature_type?) end |
#allow_resource_permissions? ⇒ Boolean
Public: Overrides the ‘allow_resource_permissions?` Resourceable concern method.
469 470 471 |
# File 'app/models/decidim/initiative.rb', line 469 def true end |
#answered? ⇒ Boolean
Public: Checks if the organization has given an answer for the initiative.
Returns a Boolean.
240 241 242 |
# File 'app/models/decidim/initiative.rb', line 240 def answered? answered_at.present? end |
#author_name ⇒ Object
Public: Returns the author name. If it has been created by an organization it will return the organization’s name. Otherwise it will return author’s name.
Returns a string
210 211 212 |
# File 'app/models/decidim/initiative.rb', line 210 def user_group&.name || .name end |
#author_users ⇒ Object
420 421 422 |
# File 'app/models/decidim/initiative.rb', line 420 def [].concat(committee_members..map(&:user)) end |
#banner_image ⇒ Object
Public: Overrides participatory space’s banner image with the banner image defined for the initiative type.
Returns Decidim::BannerImageUploader
189 190 191 |
# File 'app/models/decidim/initiative.rb', line 189 def type.attached_uploader(:banner_image) end |
#commentable? ⇒ Boolean
Public: Whether the object’s comments are visible or not.
194 195 196 |
# File 'app/models/decidim/initiative.rb', line 194 def commentable? type.comments_enabled? end |
#comments_have_alignment? ⇒ Boolean
Public: Overrides the ‘comments_have_alignment?` Commentable concern method.
401 402 403 |
# File 'app/models/decidim/initiative.rb', line 401 def comments_have_alignment? true end |
#comments_have_votes? ⇒ Boolean
Public: Overrides the ‘comments_have_votes?` Commentable concern method.
406 407 408 |
# File 'app/models/decidim/initiative.rb', line 406 def comments_have_votes? true end |
#component ⇒ Object
448 449 450 |
# File 'app/models/decidim/initiative.rb', line 448 def component nil end |
#created_by_individual? ⇒ Boolean
Public: Check if an initiative has been created by an individual person. If it is false, then it has been created by an authorized organization.
Returns a Boolean
202 203 204 |
# File 'app/models/decidim/initiative.rb', line 202 def created_by_individual? decidim_user_group_id.nil? end |
#enough_committee_members? ⇒ Boolean
440 441 442 |
# File 'app/models/decidim/initiative.rb', line 440 def enough_committee_members? committee_members.approved.count >= minimum_committee_members end |
#has_authorship?(user) ⇒ Boolean
Public: Checks if user is the author or is part of the promotal committee of the initiative.
Returns a Boolean.
414 415 416 417 418 |
# File 'app/models/decidim/initiative.rb', line 414 def (user) return true if .id == user.id committee_members.approved.where(decidim_users_id: user.id).any? end |
#has_signature_interval_defined? ⇒ Boolean
Public: Returns whether the signature interval is already defined or not.
282 283 284 |
# File 'app/models/decidim/initiative.rb', line 282 def has_signature_interval_defined? signature_end_date.present? && signature_start_date.present? end |
#hashtag ⇒ Object
Public: Returns the hashtag for the initiative.
287 288 289 |
# File 'app/models/decidim/initiative.rb', line 287 def hashtag attributes["hashtag"].to_s.delete("#") end |
#minimum_committee_members ⇒ Object
436 437 438 |
# File 'app/models/decidim/initiative.rb', line 436 def minimum_committee_members type.minimum_committee_members || Decidim::Initiatives.minimum_committee_members end |
#missing_committee_members ⇒ Object
444 445 446 |
# File 'app/models/decidim/initiative.rb', line 444 def missing_committee_members minimum_committee_members - committee_members.approved.count end |
#offline_votes_count ⇒ Object
336 337 338 339 340 |
# File 'app/models/decidim/initiative.rb', line 336 def offline_votes_count return 0 if online_signature_type? offline_votes["total"].to_i end |
#offline_votes_count_for(scope) ⇒ Object
350 351 352 353 354 355 356 |
# File 'app/models/decidim/initiative.rb', line 350 def offline_votes_count_for(scope) return 0 if online_signature_type? scope_key = (scope&.id || "global").to_s (offline_votes || {}).fetch(scope_key, 0).to_i end |
#online_votes_count ⇒ Object
Public: Calculates all the votes across all the scopes.
Returns an Integer.
330 331 332 333 334 |
# File 'app/models/decidim/initiative.rb', line 330 def online_votes_count return 0 if offline_signature_type? online_votes["total"].to_i end |
#online_votes_count_for(scope) ⇒ Object
342 343 344 345 346 347 348 |
# File 'app/models/decidim/initiative.rb', line 342 def online_votes_count_for(scope) return 0 if offline_signature_type? scope_key = (scope&.id || "global").to_s (online_votes || {}).fetch(scope_key, 0).to_i end |
#percentage ⇒ Object
Public: Returns the percentage of required supports reached
313 314 315 |
# File 'app/models/decidim/initiative.rb', line 313 def percentage [supports_count * 100 / supports_required, 100].min end |
#publish! ⇒ Object
Public: Publishes this initiative
Returns true if the record was properly saved, false otherwise.
261 262 263 264 265 266 267 268 269 270 |
# File 'app/models/decidim/initiative.rb', line 261 def publish! return false if published? update( published_at: Time.current, state: "open", signature_start_date: Date.current, signature_end_date: signature_end_date || (Date.current + Decidim::Initiatives.default_signature_time_period_length) ) end |
#reported_attributes ⇒ Object
Public: Overrides the ‘reported_attributes` Reportable concern method.
220 221 222 |
# File 'app/models/decidim/initiative.rb', line 220 def reported_attributes [:title, :description] end |
#reported_content_url ⇒ Object
Public: Overrides the ‘reported_content_url` Reportable concern method.
215 216 217 |
# File 'app/models/decidim/initiative.rb', line 215 def reported_content_url ResourceLocatorPresenter.new(self).url end |
#scopes_enabled ⇒ Object
Public: Overrides scopes enabled attribute value. For initiatives it will not be directly managed by the user and it will be enabled by default.
254 255 256 |
# File 'app/models/decidim/initiative.rb', line 254 def scopes_enabled true end |
#scopes_enabled? ⇒ Boolean
Public: Overrides scopes enabled flag available in other models like participatory space or assemblies. For initiatives it will not be directly managed by the user and it will be enabled by default.
247 248 249 |
# File 'app/models/decidim/initiative.rb', line 247 def scopes_enabled? true end |
#set_offline_votes_total ⇒ Object
370 371 372 373 374 |
# File 'app/models/decidim/initiative.rb', line 370 def set_offline_votes_total return if offline_votes.blank? offline_votes["total"] = offline_votes[scope&.id.to_s] || offline_votes["global"] end |
#shareable_url(share_token) ⇒ Object
477 478 479 |
# File 'app/models/decidim/initiative.rb', line 477 def shareable_url(share_token) EngineRouter.main_proxy(self).initiative_url(self, share_token: share_token.token) end |
#slug ⇒ Object
Public: Overrides slug attribute from participatory processes.
391 392 393 |
# File 'app/models/decidim/initiative.rb', line 391 def slug slug_from_id(id) end |
#supports_count ⇒ Object
Public: Calculates the number of total current supports.
Returns an Integer.
294 295 296 |
# File 'app/models/decidim/initiative.rb', line 294 def supports_count online_votes_count + offline_votes_count end |
#supports_count_for(scope) ⇒ Object
Public: Calculates the number of current supports for a scope.
Returns an Integer.
301 302 303 |
# File 'app/models/decidim/initiative.rb', line 301 def supports_count_for(scope) online_votes_count_for(scope) + offline_votes_count_for(scope) end |
#supports_goal_reached? ⇒ Boolean
Public: Whether the supports required objective has been reached
318 319 320 |
# File 'app/models/decidim/initiative.rb', line 318 def supports_goal_reached? votable_initiative_type_scopes.map(&:scope).all? { |scope| supports_goal_reached_for?(scope) } end |
#supports_goal_reached_for?(scope) ⇒ Boolean
Public: Whether the supports required objective has been reached for a scope
323 324 325 |
# File 'app/models/decidim/initiative.rb', line 323 def supports_goal_reached_for?(scope) supports_count_for(scope) >= supports_required_for(scope) end |
#supports_required_for(scope) ⇒ Object
Public: Calculates the number of supports required to accept the initiative for a scope.
Returns an Integer.
308 309 310 |
# File 'app/models/decidim/initiative.rb', line 308 def supports_required_for(scope) initiative_type_scopes.find_by(decidim_scopes_id: scope&.id).supports_required end |
#to_param ⇒ Object
395 396 397 |
# File 'app/models/decidim/initiative.rb', line 395 def to_param slug end |
#unpublish! ⇒ Object
Public: Unpublishes this initiative
Returns true if the record was properly saved, false otherwise.
275 276 277 278 279 |
# File 'app/models/decidim/initiative.rb', line 275 def unpublish! return false unless published? update(published_at: nil, state: "discarded") end |
#update_online_votes_counters ⇒ Object
358 359 360 361 362 363 364 365 366 367 368 |
# File 'app/models/decidim/initiative.rb', line 358 def update_online_votes_counters online_votes = votes.group(:scope).count.each_with_object({}) do |(scope, count), counters| counters[scope&.id || "global"] = count counters["total"] ||= 0 counters["total"] += count end # rubocop:disable Rails/SkipsModelValidations update_column("online_votes", online_votes) # rubocop:enable Rails/SkipsModelValidations end |
#user_allowed_to_comment?(user) ⇒ Boolean
473 474 475 |
# File 'app/models/decidim/initiative.rb', line 473 def user_allowed_to_comment?(user) ActionAuthorizer.new(user, "comment", self, nil)..ok? end |
#user_role_config_for(_user, _role_name) ⇒ Object
Public: Returns an empty object. This method should be implemented by ‘ParticipatorySpaceResourceable`, but for some reason this model does not implement this interface.
464 465 466 |
# File 'app/models/decidim/initiative.rb', line 464 def user_role_config_for(_user, _role_name) Decidim::ParticipatorySpaceRoleConfig::Base.new(:empty_role_name) end |
#validate_sms_code_on_votes? ⇒ Boolean
Public: Checks if the type the initiative belongs to enables SMS code verification step. Tis configuration is ignored if the organization does not have the sms authorization available
Returns a Boolean
457 458 459 |
# File 'app/models/decidim/initiative.rb', line 457 def validate_sms_code_on_votes? organization..include?("sms") && type.validate_sms_code_on_votes? end |
#votable_initiative_type_scopes ⇒ Object
Public: Finds all the InitiativeTypeScopes that are eligible to be voted by a user. Usually this is only the ‘scoped_type` but voting on children of the scoped type is enabled we have to filter all the available scopes in the initiative type to select the ones that are a descendant of the initiative type.
Returns an Array of Decidim::InitiativesScopeType.
382 383 384 385 386 387 388 |
# File 'app/models/decidim/initiative.rb', line 382 def votable_initiative_type_scopes return Array(scoped_type) unless type.child_scope_threshold_enabled? initiative_type_scopes.select do |initiative_type_scope| initiative_type_scope.scope.present? && (scoped_type.global_scope? || scoped_type.scope.ancestor_of?(initiative_type_scope.scope)) end.prepend(scoped_type).uniq end |
#voted_by?(user) ⇒ Boolean
Public: Check if the user has voted the question.
Returns Boolean.
233 234 235 |
# File 'app/models/decidim/initiative.rb', line 233 def voted_by?(user) votes.where(author: user).any? end |
#votes_enabled? ⇒ Boolean
224 225 226 227 228 |
# File 'app/models/decidim/initiative.rb', line 224 def votes_enabled? published? && signature_start_date <= Date.current && signature_end_date >= Date.current end |