Class: Decidim::ActionLog
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Decidim::ActionLog
- Includes:
- ScopableParticipatorySpace, Taxonomizable
- Defined in:
- decidim-core/app/models/decidim/action_log.rb
Overview
This class represents an action of a user on a resource. It is used for transparency reasons, to log all actions so all other users can see the actions being performed.
Class Method Summary collapse
-
.for_admin ⇒ Object
A scope that filters all the logs that should be visible at the admin panel.
-
.lazy_relation(id_method, klass_name, cache) ⇒ Object
Returns a Batchloader for a given class to avoid N+1 queries.
- .private_resource_types ⇒ Object
-
.public_resource_types ⇒ Object
All the resource types that are eligible to be included as an activity.
- .publicable_public_resource_types ⇒ Object
- .ransackable_associations(_auth_object = nil) ⇒ Object
- .ransackable_attributes(auth_object = nil) ⇒ Object
- .ransackable_scopes(auth_object = nil) ⇒ Object
Instance Method Summary collapse
-
#component_lazy(cache: true) ⇒ Object
Lazy loads the ‘component` association through BatchLoader, can be used as a regular object.
-
#log_presenter_class_for(log_type) ⇒ Object
Public: Finds the correct presenter class for the given ‘log_type` and the related `resource_type`.
-
#organization_lazy(cache: true) ⇒ Object
Lazy loads the ‘organization` association through BatchLoader, can be used as a regular object.
-
#participatory_space_lazy(cache: true) ⇒ Object
Lazy loads the ‘participatory_space` association through BatchLoader, can be used as a regular object.
-
#readonly? ⇒ Boolean
Overwrites the method so that records cannot be modified.
-
#resource_lazy(cache: true) ⇒ Object
Lazy loads the ‘resource` association through BatchLoader, can be used as a regular object.
-
#user_lazy(cache: true) ⇒ Object
Lazy loads the ‘user` association through BatchLoader, can be used as a regular object.
-
#visible_for?(user) ⇒ Boolean
Whether this activity or log is visible for a given user (can also be nil).
Class Method Details
.for_admin ⇒ Object
A scope that filters all the logs that should be visible at the admin panel.
125 126 127 |
# File 'decidim-core/app/models/decidim/action_log.rb', line 125 def self.for_admin where(visibility: %w(admin-only all)) end |
.lazy_relation(id_method, klass_name, cache) ⇒ Object
Returns a Batchloader for a given class to avoid N+1 queries.
Since ActionLogs are related to many different resources, loading a collection of them would trigger a lot of N+1 queries. We are using BatchLoader to accumulate and group all the resource by their class and only loading them when it is necessary.
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'decidim-core/app/models/decidim/action_log.rb', line 238 def self.lazy_relation(id_method, klass_name, cache) klass = klass_name.constantize BatchLoader.for(id_method).batch(cache:, key: klass.name.underscore) do |relation_ids, loader| scope = klass.where(id: relation_ids) scope = if klass.include?(Decidim::HasComponent) scope.where(id: relation_ids).includes(:component).where.not(decidim_components: { published_at: nil }) elsif klass.reflect_on_association(:organization) scope.where(id: relation_ids).includes(:organization) elsif klass_name == "Decidim::Comments::Comment" scope.where(id: relation_ids).includes([:moderation, :root_commentable]) else scope end scope = scope.published if klass.include?(Decidim::Publicable) scope.each { |relation| loader.call(relation.id, relation) } end end |
.private_resource_types ⇒ Object
148 149 150 151 152 153 154 |
# File 'decidim-core/app/models/decidim/action_log.rb', line 148 def self.private_resource_types @private_resource_types ||= %w( Decidim::Budgets::Order ).select do |klass| klass.safe_constantize.present? end end |
.public_resource_types ⇒ Object
All the resource types that are eligible to be included as an activity.
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'decidim-core/app/models/decidim/action_log.rb', line 130 def self.public_resource_types @public_resource_types ||= %w( Decidim::Accountability::Result Decidim::Blogs::Post Decidim::Comments::Comment Decidim::Debates::Debate Decidim::Meetings::Meeting Decidim::Proposals::Proposal Decidim::Surveys::Survey Decidim::Assembly Decidim::Conference Decidim::Initiative Decidim::ParticipatoryProcess ).select do |klass| klass.safe_constantize.present? end end |
.publicable_public_resource_types ⇒ Object
156 157 158 159 |
# File 'decidim-core/app/models/decidim/action_log.rb', line 156 def self.publicable_public_resource_types @publicable_public_resource_types ||= public_resource_types .select { |klass| klass.constantize.column_names.include?("published_at") } end |
.ransackable_associations(_auth_object = nil) ⇒ Object
175 176 177 |
# File 'decidim-core/app/models/decidim/action_log.rb', line 175 def self.ransackable_associations(_auth_object = nil) %w(user) end |
.ransackable_attributes(auth_object = nil) ⇒ Object
169 170 171 172 173 |
# File 'decidim-core/app/models/decidim/action_log.rb', line 169 def self.ransackable_attributes(auth_object = nil) return [] unless auth_object&.admin? %w(created_at) end |
.ransackable_scopes(auth_object = nil) ⇒ Object
161 162 163 164 165 166 167 |
# File 'decidim-core/app/models/decidim/action_log.rb', line 161 def self.ransackable_scopes(auth_object = nil) base = [:with_resource_type] return base unless auth_object&.admin? # Add extra scopes for admins for the admin panel searches base + [:with_participatory_space] end |
Instance Method Details
#component_lazy(cache: true) ⇒ Object
Lazy loads the ‘component` association through BatchLoader, can be used as a regular object.
188 189 190 |
# File 'decidim-core/app/models/decidim/action_log.rb', line 188 def component_lazy(cache: true) self.class.lazy_relation(decidim_component_id, "Decidim::Component", cache) end |
#log_presenter_class_for(log_type) ⇒ Object
Public: Finds the correct presenter class for the given ‘log_type` and the related `resource_type`. If no specific presenter can be found, it falls back to `Decidim::Log::BasePresenter`
log_type - a Symbol representing the log
Returns a Class.
226 227 228 229 230 |
# File 'decidim-core/app/models/decidim/action_log.rb', line 226 def log_presenter_class_for(log_type) resource_type.constantize.log_presenter_class_for(log_type) rescue NameError Decidim::Log::BasePresenter end |
#organization_lazy(cache: true) ⇒ Object
Lazy loads the ‘organization` association through BatchLoader, can be used as a regular object.
194 195 196 |
# File 'decidim-core/app/models/decidim/action_log.rb', line 194 def organization_lazy(cache: true) self.class.lazy_relation(decidim_organization_id, "Decidim::Organization", cache) end |
#participatory_space_lazy(cache: true) ⇒ Object
Lazy loads the ‘participatory_space` association through BatchLoader, can be used as a regular object.
206 207 208 209 210 211 |
# File 'decidim-core/app/models/decidim/action_log.rb', line 206 def participatory_space_lazy(cache: true) return if participatory_space_id.blank? || participatory_space_type.blank? return resource_lazy if participatory_space_id == resource_id && participatory_space_type == resource_type self.class.lazy_relation(participatory_space_id, participatory_space_type, cache) end |
#readonly? ⇒ Boolean
Overwrites the method so that records cannot be modified.
Returns a Boolean.
182 183 184 |
# File 'decidim-core/app/models/decidim/action_log.rb', line 182 def readonly? !new_record? end |
#resource_lazy(cache: true) ⇒ Object
Lazy loads the ‘resource` association through BatchLoader, can be used as a regular object.
215 216 217 |
# File 'decidim-core/app/models/decidim/action_log.rb', line 215 def resource_lazy(cache: true) self.class.lazy_relation(resource_id, resource_type, cache) end |
#user_lazy(cache: true) ⇒ Object
Lazy loads the ‘user` association through BatchLoader, can be used as a regular object.
200 201 202 |
# File 'decidim-core/app/models/decidim/action_log.rb', line 200 def user_lazy(cache: true) self.class.lazy_relation(user_id, user_type, cache) end |
#visible_for?(user) ⇒ Boolean
Whether this activity or log is visible for a given user (can also be nil)
260 261 262 263 264 265 266 267 268 269 270 |
# File 'decidim-core/app/models/decidim/action_log.rb', line 260 def visible_for?(user) resource_lazy.present? && participatory_space_lazy.present? && !resource_lazy.try(:deleted?) && !resource_lazy.try(:hidden?) && (participatory_space_lazy.try(:is_transparent?) || !resource_lazy.respond_to?(:can_participate?) || resource_lazy.try(:can_participate?, user)) rescue NameError => e Rails.logger.warn "Failed resource for #{self.class.name}(id=#{id}): #{e.message}" false end |