Skip to content

Commit

Permalink
Merge pull request #683 from alphagov/documents-and-editions
Browse files Browse the repository at this point in the history
Switch fully to documents and editions
  • Loading branch information
kevindew authored Jan 26, 2017
2 parents c478dd6 + 159a59f commit 93e7d0a
Show file tree
Hide file tree
Showing 185 changed files with 3,620 additions and 3,539 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,9 @@ for more information.
Events older then a month are archived to S3, you can import these events back
into your local DB by running the rake tasks in lib/tasks/events.rake, after
you set up the relavent ENV variables. For example if you want to find all the
events that are relavant for a particular content item you can run:
events that are relavant for a particular content_id you can run:
```sh
rake 'events:import_content_item_events[a796ca43-021b-4960-9c99-f41bb8ef2266]'
rake 'events:import_content_id_events[a796ca43-021b-4960-9c99-f41bb8ef2266]'
```
see the rake task for more details.

Expand Down
16 changes: 9 additions & 7 deletions app/commands/base_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,16 @@ def self.raise_validation_command_error(e)
end
private_class_method :execute_callbacks, :raise_validation_command_error

def check_version_and_raise_if_conflicting(current_versioned_item, previous_version_number)
current_version = LockVersion.find_by(target: current_versioned_item)
def check_version_and_raise_if_conflicting(current_versioned_item, previous_version)
return unless current_versioned_item && previous_version.present?

return unless current_versioned_item && current_version
current_version = current_versioned_item.stale_lock_version

if current_version.conflicts_with?(previous_version_number)
friendly_message = "A lock-version conflict occurred. The `previous_version` you've sent " +
"(#{previous_version_number}) is not the same as the current " +
"lock version of the content item (#{current_version.number})."
if current_version != previous_version.to_i
friendly_message = "A lock-version conflict occurred. The " +
"`previous_version` you've sent (#{previous_version}) is not the " +
"same as the current lock version of the edition " +
"(#{current_version})."

fields = {
fields: {
Expand All @@ -74,6 +75,7 @@ def check_version_and_raise_if_conflicting(current_versioned_item, previous_vers

raise_command_error(409, "Conflict", fields, friendly_message: friendly_message)
end

current_version
end

Expand Down
69 changes: 28 additions & 41 deletions app/commands/v2/discard_draft.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,37 @@ class DiscardDraft < BaseCommand
def call
raise_error_if_missing_draft!

check_version_and_raise_if_conflicting(draft, payload[:previous_version])
check_version_and_raise_if_conflicting(document, payload[:previous_version])

delete_supporting_objects
delete_supporting_objects(document.draft)
delete_draft_from_database
increment_live_lock_version if live
increment_lock_version

after_transaction_commit do
downstream_discard_draft(draft.base_path, draft.content_id, locale)
downstream_discard_draft(
document.draft.base_path,
document.content_id,
document.locale
)
end

Action.create_discard_draft_action(draft, locale, event)
Success.new(content_id: content_id)
Action.create_discard_draft_action(document.draft, document.locale, event)
Success.new(content_id: document.content_id)
end

private

def raise_error_if_missing_draft!
return if draft.present?
return if document.draft.present?

code = live.present? ? 422 : 404
message = "There is no draft content item to discard"
code = document.published_or_unpublished.present? ? 422 : 404
message = "There is not a draft edition of this document to discard"

raise CommandError.new(code: code, message: message)
end

def delete_draft_from_database
draft.destroy
document.draft.destroy
end

def downstream_discard_draft(path_used, content_id, locale)
Expand All @@ -46,43 +50,26 @@ def downstream_discard_draft(path_used, content_id, locale)
)
end

def delete_supporting_objects
Location.find_by(content_item: draft).try(:destroy)
State.find_by(content_item: draft).try(:destroy)
Translation.find_by(content_item: draft).try(:destroy)
UserFacingVersion.find_by(content_item: draft).try(:destroy)
LockVersion.find_by(target: draft).try(:destroy)
AccessLimit.find_by(content_item: draft).try(:destroy)
ChangeNote.where(content_item: draft).destroy_all
def delete_supporting_objects(edition)
Location.find_by(edition: edition).try(:destroy)
State.find_by(edition: edition).try(:destroy)
Translation.find_by(edition: edition).try(:destroy)
UserFacingVersion.find_by(edition: edition).try(:destroy)
LockVersion.find_by(target: edition).try(:destroy)
AccessLimit.find_by(edition: edition).try(:destroy)
ChangeNote.where(edition: edition).destroy_all
end

def increment_live_lock_version
LockVersion.find_by!(target: live).increment!
def increment_lock_version
document.increment!(:stale_lock_version)
end

def draft
@draft ||= ContentItem.find_by(
content_id: content_id,
locale: locale,
state: "draft",
def document
@document ||= Document.find_or_create_locked(
content_id: payload[:content_id],
locale: payload.fetch(:locale, Edition::DEFAULT_LOCALE),
)
end

def live
@live ||= ContentItem.find_by(
content_id: content_id,
locale: locale,
state: %w(published unpublished),
)
end

def content_id
payload[:content_id]
end

def locale
payload[:locale] || ContentItem::DEFAULT_LOCALE
end
end
end
end
28 changes: 6 additions & 22 deletions app/commands/v2/patch_link_set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ class PatchLinkSet < BaseCommand
def call
raise_unless_links_hash_is_provided
validate_schema
link_set = find_or_create_link_set(content_id)
link_set = LinkSet.find_or_create_locked(content_id: content_id)

check_version_and_raise_if_conflicting(link_set, previous_version_number)
LockVersion.find_or_create_by!(target: link_set).increment!

link_set.increment!(:stale_lock_version)

grouped_links.each do |group, payload_content_ids|
# For each set of links in a LinkSet scoped by link_type, this iterator
Expand All @@ -32,23 +33,6 @@ def call

private

def find_or_create_link_set(content_id)
begin
retries ||= 0
LinkSet.transaction(requires_new: true) do
LinkSet.find_or_create_by!(content_id: content_id).lock!
end
rescue ActiveRecord::RecordNotUnique
# This should never need more than 1 retry as the scenario this error
# would occur is: inbetween rails find_or_create SELECT & INSERT
# queries a concurrent request ran an INSERT. Thus on retry the
# SELECT would succeed.
# So if this actually throws an exception here we probably have a
# weird underlying problem.
retry if (retries += 1) == 1
end
end

def content_id
payload.fetch(:content_id)
end
Expand Down Expand Up @@ -82,10 +66,10 @@ def raise_unless_links_hash_is_provided
def send_downstream
return unless downstream

draft_locales = Queries::LocalesForContentItems.call([content_id])
draft_locales = Queries::LocalesForEditions.call([content_id], %w[draft live])
draft_locales.each { |(content_id, locale)| downstream_draft(content_id, locale) }

live_locales = Queries::LocalesForContentItems.call([content_id], %w[published unpublished])
live_locales = Queries::LocalesForEditions.call([content_id], %w[live])
live_locales.each { |(content_id, locale)| downstream_live(content_id, locale) }
end

Expand Down Expand Up @@ -133,7 +117,7 @@ def schema_validator

def schema_name
@schema_name ||= Queries::GetLatest.(
ContentItem.where(content_id: payload[:content_id])
Edition.with_document.where("documents.content_id": content_id)
).pluck(:schema_name).first
end
end
Expand Down
46 changes: 19 additions & 27 deletions app/commands/v2/post_action.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,51 @@ module Commands
module V2
class PostAction < BaseCommand
def call
check_version_and_raise_if_conflicting(content_item, previous_version_number)
check_version_and_raise_if_conflicting(document, previous_version_number)

Action.create!(
content_id: content_id,
locale: locale,
content_id: document.content_id,
locale: document.locale,
action: action_type,
content_item: content_item,
edition: edition,
user_uid: event.user_uid,
event: event,
)

Success.new(
{ content_id: content_id, locale: locale, action: action_type },
{ content_id: document.content_id, locale: document.locale, action: action_type },
code: 201,
)
end

private

def content_id
payload.fetch(:content_id)
end

def locale
payload.fetch(:locale, ContentItem::DEFAULT_LOCALE)
def document
@document ||= Document.find_or_create_locked(
content_id: payload.fetch(:content_id),
locale: payload.fetch(:locale, Edition::DEFAULT_LOCALE),
)
end

def draft?
payload[:draft].nil? ? true : payload[:draft]
end

def content_item
@content_item ||= find_content_item
def edition
edition = draft? ? document.draft : document.published_or_unpublished

unless edition
message = "Could not find an edition to associate this action with"
raise_command_error(404, message, fields: {})
end

edition
end

def action_type
payload[:action]
end

def find_content_item
content_item = ContentItem.find_by(
content_id: content_id,
locale: locale,
state: draft? ? %w(draft) : %w(published unpublished),
)

unless content_item
message = "Could not find a content item to associate this action with"
raise_command_error(404, message, fields: {})
end
content_item
end

def previous_version_number
payload[:previous_version].to_i if payload[:previous_version]
end
Expand Down
Loading

0 comments on commit 93e7d0a

Please sign in to comment.