-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move artefact and artefact_action table to postgres #2564
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,45 +2,9 @@ | |
require "artefact_action" # Require this when running outside Rails | ||
require_dependency "safe_html" | ||
|
||
class Artefact | ||
include Mongoid::Document | ||
include Mongoid::Timestamps | ||
|
||
class Artefact < ApplicationRecord | ||
strip_attributes only: :redirect_url | ||
|
||
field "name", type: String | ||
field "slug", type: String | ||
field "paths", type: Array, default: [] | ||
field "prefixes", type: Array, default: [] | ||
field "kind", type: String | ||
field "owning_app", type: String | ||
field "rendering_app", type: String | ||
field "active", type: Boolean, default: false | ||
|
||
field "publication_id", type: String | ||
field "description", type: String | ||
field "state", type: String, default: "draft" | ||
field "language", type: String, default: "en" | ||
field "latest_change_note", type: String | ||
field "public_timestamp", type: DateTime | ||
field "redirect_url", type: String | ||
|
||
# content_id should be unique but we have existing artefacts without it. | ||
# We should therefore enforce the uniqueness as soon as: | ||
# - every current artefact will have a content id assigned | ||
# - every future artefact will be created with a content id | ||
field "content_id", type: String | ||
|
||
index({ slug: 1 }, unique: true) | ||
|
||
# This index allows the `relatable_artefacts` method to use an index-covered | ||
# query, so it doesn't have to load each of the artefacts. | ||
index name: 1, | ||
state: 1, | ||
kind: 1, | ||
_type: 1, | ||
_id: 1 | ||
|
||
scope :not_archived, -> { where(:state.nin => %w[archived]) } | ||
|
||
FORMATS_BY_DEFAULT_OWNING_APP = { | ||
|
@@ -82,17 +46,16 @@ def self.default_app_for_format(format) | |
"find my nearest" => "place", | ||
}.tap { |h| h.default_proc = ->(_, k) { k } }.freeze | ||
|
||
embeds_many :actions, class_name: "ArtefactAction", order: { created_at: :asc } | ||
has_many :artefact_actions, -> { order(created_at: :asc) }, class_name: "ArtefactAction", dependent: :destroy | ||
|
||
embeds_many :external_links, class_name: "ArtefactExternalLink" | ||
has_many :external_links, class_name: "ArtefactExternalLink" | ||
baisa marked this conversation as resolved.
Show resolved
Hide resolved
|
||
accepts_nested_attributes_for :external_links, | ||
allow_destroy: true, | ||
reject_if: proc { |attrs| attrs["title"].blank? && attrs["url"].blank? } | ||
|
||
before_validation :normalise, on: :create | ||
before_create :record_create_action | ||
before_update :record_update_action | ||
before_update :remember_if_slug_has_changed | ||
after_update :update_editions | ||
|
||
validates :name, presence: { message: "Enter a title" } | ||
|
@@ -146,7 +109,7 @@ def any_editions_ever_published? | |
def update_editions | ||
return archive_editions if state == "archived" | ||
|
||
if @slug_was_changed | ||
if saved_change_to_attribute?("slug") | ||
Edition.draft_in_publishing_api.where(panopticon_id: id).each do |edition| | ||
edition.update_slug_from_artefact(self) | ||
end | ||
|
@@ -171,25 +134,24 @@ def update_as(user, *args) | |
save_as user | ||
end | ||
|
||
# Return value is used in caller chain to show errors | ||
# rubocop:disable Rails/SaveBang | ||
# 'valid?' populates the error context for the instance which is used in caller chain to show errors | ||
def save_as(user, options = {}) | ||
default_action = new_record? ? "create" : "update" | ||
action_type = options.delete(:action_type) || default_action | ||
record_action(action_type, user:) | ||
save(options) | ||
|
||
save! if valid? | ||
end | ||
# rubocop:enable Rails/SaveBang | ||
|
||
# We should use this method when performing save actions from rake tasks, | ||
# message queue consumer or any other performed tasks that have no user associated | ||
# as we are still interested to know what triggered the action. | ||
def save_as_task!(task_name, options = {}) | ||
default_action = new_record? ? "create" : "update" | ||
action_type = options.delete(:action_type) || default_action | ||
|
||
record_action(action_type, task_name:) | ||
save!(options) | ||
|
||
save! if valid? | ||
end | ||
|
||
def record_create_action | ||
|
@@ -204,7 +166,7 @@ def record_action(action_type, options = {}) | |
user = options[:user] | ||
task_name = options[:task_name] | ||
current_snapshot = snapshot | ||
last_snapshot = actions.last.snapshot if actions.last | ||
last_snapshot = artefact_actions.last.snapshot if artefact_actions.last | ||
|
||
unless current_snapshot == last_snapshot | ||
|
||
|
@@ -216,25 +178,7 @@ def record_action(action_type, options = {}) | |
attributes[:user] = user if user | ||
attributes[:task_performed_by] = task_name if task_name | ||
|
||
# Temp-to-be-removed | ||
# This will be removed once we move artefact table to postgres, currently record_action | ||
# when called with options contains the user object attributes that is supported by belongs to | ||
# the below code allows to use the user id foreign key instead as we are temporarily not using belongs to | ||
# relationship between artefact and user | ||
add_user_id_and_delete_user_key(attributes) | ||
mtaylorgds marked this conversation as resolved.
Show resolved
Hide resolved
|
||
new_action = actions.build(attributes) | ||
# Mongoid will not fire creation callbacks on embedded documents, so we | ||
# need to trigger this manually. There is a `cascade_callbacks` option on | ||
# `embeds_many`, but it doesn't appear to trigger creation events on | ||
# children when an update event fires on the parent | ||
new_action.set_created_at | ||
end | ||
end | ||
|
||
def add_user_id_and_delete_user_key(attributes) | ||
if attributes[:user] | ||
attributes[:user_id] = attributes[:user].id | ||
attributes.delete(:user) | ||
artefact_actions.build(attributes) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure why we need to add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is to build the artefact action which will then get saved by a callback when artefact gets saved. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes that is what happened! not sure why diff shows so strangely here! Makes sense now! |
||
end | ||
end | ||
|
||
|
@@ -248,7 +192,7 @@ def live? | |
|
||
def snapshot | ||
attributes | ||
.except("_id", "created_at", "updated_at", "actions") | ||
.except("id", "created_at", "updated_at", "artefact_actions") | ||
end | ||
|
||
def latest_edition | ||
|
@@ -285,12 +229,6 @@ def exact_route? | |
|
||
private | ||
|
||
# We need to do this because Mongoid doesn't implement 'saved_change_to_attribute?' methods like ActiveRecord does | ||
# https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Dirty.html#method-i-saved_change_to_attribute-3F | ||
def remember_if_slug_has_changed | ||
@slug_was_changed = slug_changed? | ||
end | ||
|
||
def edition_class_name | ||
"#{kind.camelcase}Edition" | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
class CreateArtefactAction < ActiveRecord::Migration[7.1] | ||
def change | ||
create_table :artefact_actions do |t| | ||
t.string :action_type | ||
mtaylorgds marked this conversation as resolved.
Show resolved
Hide resolved
|
||
t.jsonb :snapshot | ||
t.string :task_performed_by | ||
t.timestamps | ||
t.references :user, foreign_key: true | ||
t.references :artefact, index: true, foreign_key: true | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
class CreateArtefact < ActiveRecord::Migration[7.1] | ||
def change | ||
create_table :artefacts do |t| | ||
t.string :name | ||
t.string :slug | ||
t.string :paths, array: true, default: [] | ||
t.string :prefixes, array: true, default: [] | ||
t.string :kind | ||
t.string :owning_app | ||
t.string :rendering_app | ||
t.boolean :active, default: false | ||
t.string :publication_id | ||
t.string :description | ||
t.string :state, default: "draft" | ||
t.string :language, default: "en" | ||
t.string :latest_change_note | ||
t.datetime :public_timestamp | ||
t.string :redirect_url | ||
t.string :content_id | ||
t.timestamps | ||
t.index %i[name state kind id] | ||
t.index :slug, unique: true | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
class CreateArtefactExternalLink < ActiveRecord::Migration[7.1] | ||
def change | ||
create_table :artefact_external_links do |t| | ||
t.string :title | ||
t.string :url | ||
t.references :artefact, foreign_key: true | ||
t.timestamps | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
have kept this like for like and not added a validation on uniqueness, have a made a note of it to comeback during migration when I know if there are non-unique content id's