1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-12-11 22:24:21 +01:00
fab-manager/app/models/project.rb

158 lines
5.1 KiB
Ruby
Raw Normal View History

2019-06-06 16:34:53 +02:00
# frozen_string_literal: true
# Project is the documentation about an object built by a fab-user
# It can describe the steps taken by the fab-user to build his object, provide photos, description, attached CAO files, etc.
2020-03-25 10:16:47 +01:00
class Project < ApplicationRecord
2015-05-05 03:10:25 +02:00
include AASM
include NotifyWith::NotificationAttachedObject
2016-04-20 18:13:36 +02:00
include OpenlabSync
2015-05-05 03:10:25 +02:00
2016-03-23 18:39:41 +01:00
# elastic initialisations
include Elasticsearch::Model
index_name 'fablab'
document_type 'projects'
# kaminari
2019-06-06 16:34:53 +02:00
# -- dependency in app/assets/javascripts/controllers/projects.js.erb
paginates_per 16
2016-03-23 18:39:41 +01:00
# friendlyId
2015-05-05 03:10:25 +02:00
extend FriendlyId
friendly_id :name, use: :slugged
has_one :project_image, as: :viewable, dependent: :destroy
accepts_nested_attributes_for :project_image, allow_destroy: true
has_many :project_caos, as: :viewable, dependent: :destroy
2015-05-18 10:16:21 +02:00
accepts_nested_attributes_for :project_caos, allow_destroy: true, reject_if: :all_blank
2015-05-05 03:10:25 +02:00
2019-06-06 16:34:53 +02:00
has_and_belongs_to_many :machines, join_table: 'projects_machines'
has_and_belongs_to_many :spaces, join_table: 'projects_spaces'
has_and_belongs_to_many :components, join_table: 'projects_components'
has_and_belongs_to_many :themes, join_table: 'projects_themes'
2015-05-05 03:10:25 +02:00
has_many :project_users, dependent: :destroy
has_many :users, through: :project_users
2019-06-06 16:34:53 +02:00
belongs_to :author, foreign_key: :author_statistic_profile_id, class_name: 'StatisticProfile'
2015-05-05 03:10:25 +02:00
belongs_to :licence, foreign_key: :licence_id
has_many :project_steps, dependent: :destroy
accepts_nested_attributes_for :project_steps, allow_destroy: true
2016-04-21 17:10:50 +02:00
# validations
validates :author, :name, presence: true
2015-05-05 03:10:25 +02:00
after_save :after_save_and_publish
2019-06-06 16:34:53 +02:00
aasm column: 'state' do
2015-05-05 03:10:25 +02:00
state :draft, initial: true
state :published
2019-06-06 16:34:53 +02:00
event :publish, after: :notify_admin_when_project_published do
transitions from: :draft, to: :published
2015-05-05 03:10:25 +02:00
end
end
2019-06-06 16:34:53 +02:00
# scopes
2015-05-05 03:10:25 +02:00
scope :published, -> { where("state = 'published'") }
2016-03-23 18:39:41 +01:00
## elastic
# callbacks
2019-06-06 16:34:53 +02:00
after_save { ProjectIndexerWorker.perform_async(:index, id) }
after_destroy { ProjectIndexerWorker.perform_async(:delete, id) }
2016-03-23 18:39:41 +01:00
# mapping
settings index: { number_of_replicas: 0 } do
2016-03-23 18:39:41 +01:00
mappings dynamic: 'true' do
indexes 'state', analyzer: 'simple'
indexes 'tags', analyzer: Rails.application.secrets.elasticsearch_language_analyzer
indexes 'name', analyzer: Rails.application.secrets.elasticsearch_language_analyzer
indexes 'description', analyzer: Rails.application.secrets.elasticsearch_language_analyzer
indexes 'project_steps' do
2019-06-06 16:34:53 +02:00
indexes 'title', analyzer: Rails.application.secrets.elasticsearch_language_analyzer
indexes 'description', analyzer: Rails.application.secrets.elasticsearch_language_analyzer
2016-03-23 18:39:41 +01:00
end
end
end
# the resulting JSON will be indexed in ElasticSearch, as /fablab/projects
2016-03-23 18:39:41 +01:00
def as_indexed_json
2019-06-06 16:34:53 +02:00
ApplicationController.new.view_context.render(
partial: 'api/projects/indexed',
locals: { project: self },
formats: [:json],
handlers: [:jbuilder]
)
2016-03-23 18:39:41 +01:00
end
def self.search(params, current_user)
Project.__elasticsearch__.search(build_search_query_from_context(params, current_user))
end
def self.build_search_query_from_context(params, current_user)
search = {
query: {
2018-06-05 12:30:08 +02:00
bool: {
must: [],
should: [],
2019-06-06 16:34:53 +02:00
filter: []
2016-03-23 18:39:41 +01:00
}
}
}
2019-06-06 16:34:53 +02:00
# we sort by created_at if there isn't a query
if params['q'].blank?
2016-03-23 18:39:41 +01:00
search[:sort] = { created_at: { order: :desc } }
2019-06-06 16:34:53 +02:00
else
# otherwise we search for the word (q) in various fields
2018-06-05 12:30:08 +02:00
search[:query][:bool][:must] << {
2016-03-23 18:39:41 +01:00
multi_match: {
query: params['q'],
type: 'most_fields',
2019-06-06 16:34:53 +02:00
fields: %w[tags^4 name^5 description^3 project_steps.title^2 project_steps.description]
2016-03-23 18:39:41 +01:00
}
}
end
2019-06-06 16:34:53 +02:00
# we filter by themes, components, machines
params.each do |name, value|
2016-03-23 18:39:41 +01:00
if name =~ /(.+_id$)/
2018-06-05 12:30:08 +02:00
search[:query][:bool][:filter] << { term: { "#{name}s" => value } } if value
2016-03-23 18:39:41 +01:00
end
end
2019-06-06 16:34:53 +02:00
# if use select filter 'my project' or 'my collaborations'
if current_user && params.key?('from')
search[:query][:bool][:filter] << { term: { author_id: current_user.id } } if params['from'] == 'mine'
search[:query][:bool][:filter] << { term: { user_ids: current_user.id } } if params['from'] == 'collaboration'
2016-03-23 18:39:41 +01:00
end
2019-06-06 16:34:53 +02:00
# if user is connected, also display his draft projects
if current_user
2018-06-05 12:30:08 +02:00
search[:query][:bool][:should] << { term: { state: 'published' } }
search[:query][:bool][:should] << { term: { author_id: current_user.id } }
search[:query][:bool][:should] << { term: { user_ids: current_user.id } }
2019-06-06 16:34:53 +02:00
else
# otherwise display only published projects
2018-06-05 12:30:08 +02:00
search[:query][:bool][:must] << { term: { state: 'published' } }
2016-03-23 18:39:41 +01:00
end
search
end
2015-05-05 03:10:25 +02:00
private
2019-06-06 16:34:53 +02:00
2015-05-05 03:10:25 +02:00
def notify_admin_when_project_published
NotificationCenter.call type: 'notify_admin_when_project_published',
2020-04-29 15:34:30 +02:00
receiver: User.admins_and_managers,
2015-05-05 03:10:25 +02:00
attached_object: self
end
def after_save_and_publish
return unless saved_change_to_state? && published?
2019-06-06 16:34:53 +02:00
update_columns(published_at: DateTime.current)
2019-06-06 16:34:53 +02:00
notify_admin_when_project_published
2015-05-05 03:10:25 +02:00
end
end