Merge pull request #3811 from consul/investment_changelog
Use audited to track changes in investments
This commit is contained in:
@@ -208,6 +208,7 @@ Rails/CreateTableWithTimestamps:
|
||||
Enabled: true
|
||||
Exclude:
|
||||
- "db/migrate/201[5-8]*"
|
||||
- "db/migrate/*install_audited.rb"
|
||||
|
||||
Rails/Date:
|
||||
Enabled: true
|
||||
|
||||
1
Gemfile
1
Gemfile
@@ -6,6 +6,7 @@ gem "acts-as-taggable-on", "~> 5.0.0"
|
||||
gem "acts_as_votable", "~> 0.11.1"
|
||||
gem "ahoy_matey", "~> 1.6.0"
|
||||
gem "ancestry", "~> 3.0.7"
|
||||
gem "audited", "~> 4.9.0"
|
||||
gem "autoprefixer-rails", "~> 8.2.0"
|
||||
gem "axlsx", "~> 3.0.0.pre"
|
||||
gem "axlsx_rails", "~> 0.5.2"
|
||||
|
||||
@@ -72,6 +72,8 @@ GEM
|
||||
activerecord (>= 3.2.0)
|
||||
arel (7.1.4)
|
||||
ast (2.4.0)
|
||||
audited (4.9.0)
|
||||
activerecord (>= 4.2, < 6.1)
|
||||
autoprefixer-rails (8.2.0)
|
||||
execjs
|
||||
axlsx (3.0.0.pre)
|
||||
@@ -588,6 +590,7 @@ DEPENDENCIES
|
||||
acts_as_votable (~> 0.11.1)
|
||||
ahoy_matey (~> 1.6.0)
|
||||
ancestry (~> 3.0.7)
|
||||
audited (~> 4.9.0)
|
||||
autoprefixer-rails (~> 8.2.0)
|
||||
axlsx (~> 3.0.0.pre)
|
||||
axlsx_rails (~> 0.5.2)
|
||||
|
||||
@@ -595,17 +595,6 @@ code {
|
||||
}
|
||||
}
|
||||
|
||||
.log-value {
|
||||
max-height: rem-calc(65);
|
||||
overflow: hidden;
|
||||
max-width: rem-calc(200);
|
||||
|
||||
&:hover {
|
||||
max-height: rem-calc(1000);
|
||||
transition: max-height 0.9s;
|
||||
}
|
||||
}
|
||||
|
||||
// 04. Stats
|
||||
// ---------
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
class Admin::BudgetInvestmentAuditsController < Admin::BaseController
|
||||
def show
|
||||
investment = Budget::Investment.find(params[:budget_investment_id])
|
||||
@audit = investment.own_and_associated_audits.find(params[:id])
|
||||
|
||||
render "admin/audits/show"
|
||||
end
|
||||
end
|
||||
@@ -2,7 +2,6 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
|
||||
include FeatureFlags
|
||||
include CommentableActions
|
||||
include DownloadSettingsHelper
|
||||
include ChangeLogHelper
|
||||
include Translatable
|
||||
|
||||
feature_flag :budgets
|
||||
@@ -10,12 +9,11 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
|
||||
has_orders %w[oldest], only: [:show, :edit]
|
||||
has_filters %w[all], only: [:index, :toggle_selection]
|
||||
|
||||
before_action :load_budget, except: :show_investment_log
|
||||
before_action :load_budget
|
||||
before_action :load_investment, only: [:show, :edit, :update, :toggle_selection]
|
||||
before_action :load_ballot, only: [:show, :index]
|
||||
before_action :parse_valuation_filters
|
||||
before_action :load_investments, only: [:index, :toggle_selection]
|
||||
before_action :load_change_log, only: [:show]
|
||||
|
||||
def index
|
||||
load_tags
|
||||
@@ -128,8 +126,4 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def load_change_log
|
||||
@logs = Budget::Investment::ChangeLog.by_investment(@investment.id)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,7 +15,6 @@ class ApplicationController < ActionController::Base
|
||||
before_action :set_locale
|
||||
before_action :track_email_campaign
|
||||
before_action :set_return_url
|
||||
before_action :set_current_user
|
||||
|
||||
check_authorization unless: :devise_controller?
|
||||
self.responder = ApplicationResponder
|
||||
@@ -121,8 +120,4 @@ class ApplicationController < ActionController::Base
|
||||
def current_budget
|
||||
Budget.current
|
||||
end
|
||||
|
||||
def set_current_user
|
||||
User.current_user = current_user
|
||||
end
|
||||
end
|
||||
|
||||
15
app/helpers/audits_helper.rb
Normal file
15
app/helpers/audits_helper.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
module AuditsHelper
|
||||
def truncate_audit_value(resource, field, value)
|
||||
truncate(audit_value(resource, field, value), length: 50)
|
||||
end
|
||||
|
||||
def audit_value(resource, field, value)
|
||||
if value.is_a?(Array)
|
||||
value.join(",")
|
||||
elsif resource.type_for_attribute(field.to_s).type == :boolean
|
||||
resource.class.human_attribute_name("#{field}_#{value}")
|
||||
else
|
||||
value.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,6 +0,0 @@
|
||||
module ChangeLogHelper
|
||||
def show_investment_log
|
||||
@log = Budget::Investment::ChangeLog.find_by(id: params[:id])
|
||||
render "admin/change_logs/show"
|
||||
end
|
||||
end
|
||||
2
app/models/audit.rb
Normal file
2
app/models/audit.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
class Audit < Audited::Audit
|
||||
end
|
||||
@@ -3,7 +3,6 @@ class Budget
|
||||
class Investment < ApplicationRecord
|
||||
SORTING_OPTIONS = { id: "id", supports: "cached_votes_up" }.freeze
|
||||
|
||||
include ActiveModel::Dirty
|
||||
include Rails.application.routes.url_helpers
|
||||
include Measurable
|
||||
include Sanitizable
|
||||
@@ -33,6 +32,13 @@ class Budget
|
||||
translates :description, touch: true
|
||||
include Globalizable
|
||||
|
||||
audited on: [:update, :destroy]
|
||||
has_associated_audits
|
||||
translation_class.class_eval do
|
||||
audited associated_with: :globalized_model,
|
||||
only: Budget::Investment.translated_attribute_names
|
||||
end
|
||||
|
||||
belongs_to :author, -> { with_hidden }, class_name: "User", inverse_of: :budget_investments
|
||||
belongs_to :heading
|
||||
belongs_to :group
|
||||
@@ -115,7 +121,6 @@ class Budget
|
||||
after_save :recalculate_heading_winners
|
||||
before_validation :set_responsible_name
|
||||
before_validation :set_denormalized_ids
|
||||
after_update :change_log
|
||||
|
||||
def comments_count
|
||||
comments.count
|
||||
@@ -404,20 +409,6 @@ class Budget
|
||||
self.original_heading_id = heading_id
|
||||
end
|
||||
|
||||
def change_log
|
||||
self.changed.each do |field|
|
||||
unless field == "updated_at"
|
||||
log = Budget::Investment::ChangeLog.new
|
||||
log.field = field
|
||||
log.author_id = User.current_user.id unless User.current_user.nil?
|
||||
log.investment_id = self.id
|
||||
log.new_value = self.send field
|
||||
log.old_value = self.send "#{field}_was"
|
||||
!log.save
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def searchable_translations_definitions
|
||||
{ title => "A",
|
||||
description => "D" }
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
class Budget::Investment::ChangeLog < ApplicationRecord
|
||||
belongs_to :author, -> { with_hidden },
|
||||
class_name: "User",
|
||||
foreign_key: "author_id",
|
||||
inverse_of: :budget_investment_change_logs,
|
||||
required: false
|
||||
|
||||
validates :old_value, presence: true
|
||||
validates :new_value, presence: true
|
||||
validates :field, presence: true
|
||||
|
||||
scope :by_investment, ->(investment_id) { where(investment_id: investment_id) }
|
||||
end
|
||||
@@ -27,10 +27,6 @@ class User < ApplicationRecord
|
||||
class_name: "Budget::Investment",
|
||||
foreign_key: :author_id,
|
||||
inverse_of: :author
|
||||
has_many :budget_investment_change_logs,
|
||||
foreign_key: :author_id,
|
||||
inverse_of: :author,
|
||||
class_name: "Budget::Investment::ChangeLog"
|
||||
has_many :comments, -> { with_hidden }, inverse_of: :user
|
||||
has_many :failed_census_calls
|
||||
has_many :notifications
|
||||
@@ -400,14 +396,6 @@ class User < ApplicationRecord
|
||||
followables.compact.map { |followable| followable.tags.map(&:name) }.flatten.compact.uniq
|
||||
end
|
||||
|
||||
def self.current_user
|
||||
Thread.current[:user]
|
||||
end
|
||||
|
||||
def self.current_user=(user)
|
||||
Thread.current[:user] = user
|
||||
end
|
||||
|
||||
def send_devise_notification(notification, *args)
|
||||
devise_mailer.send(notification, self, *args).deliver_later
|
||||
end
|
||||
|
||||
46
app/views/admin/audits/_audits.html.erb
Normal file
46
app/views/admin/audits/_audits.html.erb
Normal file
@@ -0,0 +1,46 @@
|
||||
<h2><%= t("admin.audits.title") %></h2>
|
||||
|
||||
<% if resource.audits.empty? %>
|
||||
<p><%= t("admin.audits.empty") %></p>
|
||||
<% else %>
|
||||
<table id="audits">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><%= t("admin.audits.id") %></th>
|
||||
<th><%= t("admin.audits.field") %></th>
|
||||
<th><%= t("admin.audits.old_value") %></th>
|
||||
<th><%= t("admin.audits.new_value") %></th>
|
||||
<th><%= t("admin.audits.edited_at") %></th>
|
||||
<th><%= t("admin.audits.edited_by") %></th>
|
||||
<th><%= t("admin.audits.actions") %></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% resource.own_and_associated_audits.order(:created_at).each do |audit| %>
|
||||
<% audit.audited_changes.each do |field, (old_value, new_value)| %>
|
||||
<tr>
|
||||
<td class="text-center"><%= audit.id %></td>
|
||||
<td class="small"><%= sanitize(resource.class.human_attribute_name(field)) %></td>
|
||||
<td class="small">
|
||||
<div class="audit-value"><%= truncate_audit_value(resource, field, old_value) %></div>
|
||||
</td>
|
||||
<td class="small">
|
||||
<div class="audit-value"><%= truncate_audit_value(resource, field, new_value) %></div>
|
||||
</td>
|
||||
<td class="small">
|
||||
<%= l audit.created_at.to_date %>
|
||||
</td>
|
||||
<td class="small">
|
||||
<%= audit.user&.name %>
|
||||
</td>
|
||||
<td>
|
||||
<%= link_to t("shared.show"),
|
||||
polymorphic_path([:admin, *resource_hierarchy_for(audit)]),
|
||||
class: "button hollow primary" %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<% end %>
|
||||
20
app/views/admin/audits/show.html.erb
Normal file
20
app/views/admin/audits/show.html.erb
Normal file
@@ -0,0 +1,20 @@
|
||||
<% provide(:title) do %>
|
||||
<%= t("admin.audits.title") %>
|
||||
<% end %>
|
||||
<%= back_link_to polymorphic_path([:admin, *resource_hierarchy_for(@audit.associated || @audit.auditable)]) %>
|
||||
|
||||
<h2><%= t("admin.audits.title") %></h2>
|
||||
|
||||
<p><strong><%= t("admin.audits.edited_at") %></strong> <%= l @audit.created_at.to_date %></p>
|
||||
<p><strong><%= t("admin.audits.edited_by") %></strong> <%= @audit.user&.name %></p>
|
||||
|
||||
<h3><%= t("admin.audits.changes") %></h3>
|
||||
|
||||
<% @audit.audited_changes.each do |field, (old_value, new_value)| %>
|
||||
<strong><%= t("admin.audits.field") %></strong>
|
||||
<p><%= sanitize(@audit.auditable.class.human_attribute_name(field)) %></p>
|
||||
<strong><%= t("admin.audits.old_value") %></strong>
|
||||
<p><%= wysiwyg(audit_value(@audit.auditable, field, old_value)) %></p>
|
||||
<strong><%= t("admin.audits.new_value") %></strong>
|
||||
<p><%= wysiwyg(audit_value(@audit.auditable, field, new_value)) %></p>
|
||||
<% end %>
|
||||
@@ -41,7 +41,7 @@
|
||||
<div class="small-12 medium-4 column">
|
||||
<p>
|
||||
<strong><%= t("admin.budget_investments.show.selection.title") %></strong>:
|
||||
<%= t("admin.budget_investments.show.selection.#{@investment.selected?}") %>
|
||||
<%= @investment.class.human_attribute_name("selected_#{@investment.selected?}") %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="small-12 medium-4 column">
|
||||
|
||||
@@ -66,6 +66,6 @@
|
||||
|
||||
<%= render "valuation/budget_investments/valuation_comments" %>
|
||||
|
||||
<%= render "admin/change_logs/change_log", logs: @logs %>
|
||||
<%= render "admin/audits/audits", resource: @investment %>
|
||||
|
||||
<%= render "admin/milestones/milestones", milestoneable: @investment %>
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
<h2 class="inline-block"><%= t("admin.change_log.title") %></h2>
|
||||
|
||||
<% if logs.empty? %>
|
||||
<label><%= t("admin.change_log.empty") %></label>
|
||||
<% else %>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><%= t("admin.change_log.id") %></th>
|
||||
<th><%= t("admin.change_log.field") %></th>
|
||||
<th><%= t("admin.change_log.old_value") %></th>
|
||||
<th><%= t("admin.change_log.new_value") %></th>
|
||||
<th><%= t("admin.change_log.edited_at") %></th>
|
||||
<th><%= t("admin.change_log.edited_by") %></th>
|
||||
<th><%= t("admin.change_log.actions") %></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% logs.each do |log| %>
|
||||
<tr id="log_<%= log.id %>">
|
||||
<td class="text-center"><%= log.id %></td>
|
||||
<td class="small"><%= log.field.capitalize %></td>
|
||||
<td class="small">
|
||||
<div class="log-value"><%= log.old_value %></div>
|
||||
</td>
|
||||
<td class="small">
|
||||
<div class="log-value"><%= log.new_value %></div>
|
||||
</td>
|
||||
<td class="small">
|
||||
<%= log.created_at.to_date %>
|
||||
</td>
|
||||
<td class="small">
|
||||
<%= log.author.name unless log.author.nil? %>
|
||||
</td>
|
||||
<td>
|
||||
<%= link_to admin_change_log_path(id: log) do %>
|
||||
<button class="button hollow primary"><%= t("shared.show") %></button>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<% end %>
|
||||
@@ -1,12 +0,0 @@
|
||||
<h2 class="inline-block"><%= t("admin.change_log.title") %></h2>
|
||||
|
||||
<label><strong><%= t("admin.change_log.id") %></strong></label>
|
||||
<p><%= @log.id %></p>
|
||||
<label><strong><%= t("admin.change_log.old_value") %></strong></label>
|
||||
<p><%= @log.old_value %></p>
|
||||
<label><strong><%= t("admin.change_log.new_value") %></strong></label>
|
||||
<p><%= @log.new_value %></p>
|
||||
<label><strong><%= t("admin.change_log.edited_at") %></strong></label>
|
||||
<p><%= @log.created_at.to_date %></p>
|
||||
<label><strong><%= t("admin.change_log.edited_by") %></strong></label>
|
||||
<p><%= @log.author.name unless @log.author.nil? %></p>
|
||||
3
config/initializers/audited.rb
Normal file
3
config/initializers/audited.rb
Normal file
@@ -0,0 +1,3 @@
|
||||
Audited.config do |config|
|
||||
config.audit_class = ::Audit
|
||||
end
|
||||
@@ -13,6 +13,8 @@ module ActionDispatch::Routing::UrlFor
|
||||
[*resource_hierarchy_for(resource.milestoneable), resource]
|
||||
when "ProgressBar"
|
||||
[*resource_hierarchy_for(resource.progressable), resource]
|
||||
when "Audit"
|
||||
[*resource_hierarchy_for(resource.associated || resource.auditable), resource]
|
||||
when "Legislation::Annotation"
|
||||
[resource.draft_version.process, resource.draft_version, resource]
|
||||
when "Legislation::Proposal", "Legislation::Question", "Legislation::DraftVersion"
|
||||
|
||||
@@ -161,6 +161,8 @@ en:
|
||||
milestone_tag_list: "Milestone tags"
|
||||
price_explanation: "Price explanation"
|
||||
selected: "Mark as selected"
|
||||
selected_true: "Selected"
|
||||
selected_false: "Not selected"
|
||||
unfeasibility_explanation: "Feasibility explanation"
|
||||
valuation_finished: "Valuation finished"
|
||||
valuator_ids: "Groups"
|
||||
|
||||
@@ -241,8 +241,6 @@ en:
|
||||
"false": Compatible
|
||||
selection:
|
||||
title: Selection
|
||||
"true": Selected
|
||||
"false": Not selected
|
||||
winner:
|
||||
title: Winner
|
||||
"true": "Yes"
|
||||
@@ -1583,8 +1581,9 @@ en:
|
||||
submit_header: Save header
|
||||
card_title: Edit card
|
||||
submit_card: Save card
|
||||
change_log:
|
||||
audits:
|
||||
title: "Change Log"
|
||||
changes: "List of changes"
|
||||
id: "ID"
|
||||
field: "Field"
|
||||
new_value: "New Value"
|
||||
@@ -1592,7 +1591,7 @@ en:
|
||||
edited_at: "Edited at"
|
||||
edited_by: "Edited by"
|
||||
actions: "Actions"
|
||||
empty: "There are not changes logged"
|
||||
empty: "There are no changes logged"
|
||||
local_census_records:
|
||||
index:
|
||||
title: Manage local census
|
||||
|
||||
@@ -163,6 +163,8 @@ es:
|
||||
milestone_tag_list: "Etiquetas de Seguimiento"
|
||||
price_explanation: "Informe de coste <small>(opcional, dato público)</small>"
|
||||
selected: "Marcar como seleccionado"
|
||||
selected_true: "Seleccionado"
|
||||
selected_false: "No seleccionado"
|
||||
unfeasibility_explanation: "Informe de inviabilidad <small>(en caso de que lo sea, dato público)</small>"
|
||||
valuation_finished: "Informe finalizado"
|
||||
valuator_ids: "Grupos"
|
||||
|
||||
@@ -241,8 +241,6 @@ es:
|
||||
"false": Compatible
|
||||
selection:
|
||||
title: Selección
|
||||
"true": Seleccionado
|
||||
"false": No seleccionado
|
||||
winner:
|
||||
title: Ganador
|
||||
"true": "Si"
|
||||
@@ -1582,8 +1580,9 @@ es:
|
||||
submit_header: Guardar encabezado
|
||||
card_title: Editar tarjeta
|
||||
submit_card: Guardar tarjeta
|
||||
change_log:
|
||||
audits:
|
||||
title: "Historial"
|
||||
changes: "Lista de cambios"
|
||||
id: "ID"
|
||||
field: "Campo"
|
||||
new_value: "Valor nuevo"
|
||||
|
||||
@@ -63,6 +63,7 @@ namespace :admin do
|
||||
resources :budget_investments, only: [:index, :show, :edit, :update] do
|
||||
member { patch :toggle_selection }
|
||||
|
||||
resources :audits, only: :show, controller: "budget_investment_audits"
|
||||
resources :milestones, controller: "budget_investment_milestones"
|
||||
resources :progress_bars, except: :show, controller: "budget_investment_progress_bars"
|
||||
end
|
||||
@@ -250,8 +251,6 @@ namespace :admin do
|
||||
get "download_settings/:resource", to: "download_settings#edit", as: "edit_download_settings"
|
||||
put "download_settings/:resource", to: "download_settings#update", as: "update_download_settings"
|
||||
|
||||
get "/change_log/:id", to: "budget_investments#show_investment_log", as: "change_log"
|
||||
|
||||
resources :local_census_records
|
||||
namespace :local_census_records do
|
||||
resources :imports, only: [:new, :create, :show]
|
||||
|
||||
@@ -121,13 +121,16 @@ section "Creating Investments" do
|
||||
100.times do
|
||||
heading = Budget::Heading.all.sample
|
||||
|
||||
investment = Budget::Investment.create!(
|
||||
translation_attributes = random_locales.each_with_object({}) do |locale, attributes|
|
||||
attributes["title_#{locale.to_s.underscore}"] = "Title for locale #{locale}"
|
||||
attributes["description_#{locale.to_s.underscore}"] = "<p>Description for locale #{locale}</p>"
|
||||
end
|
||||
|
||||
investment = Budget::Investment.create!({
|
||||
author: User.all.sample,
|
||||
heading: heading,
|
||||
group: heading.group,
|
||||
budget: heading.group.budget,
|
||||
title: Faker::Lorem.sentence(3).truncate(60),
|
||||
description: "<p>#{Faker::Lorem.paragraphs.join("</p><p>")}</p>",
|
||||
created_at: rand((Time.current - 1.week)..Time.current),
|
||||
feasibility: %w[undecided unfeasible feasible feasible feasible feasible].sample,
|
||||
unfeasibility_explanation: Faker::Lorem.paragraph,
|
||||
@@ -136,15 +139,7 @@ section "Creating Investments" do
|
||||
price: rand(1..100) * 100000,
|
||||
skip_map: "1",
|
||||
terms_of_service: "1"
|
||||
)
|
||||
|
||||
random_locales.map do |locale|
|
||||
Globalize.with_locale(locale) do
|
||||
investment.title = "Title for locale #{locale}"
|
||||
investment.description = "<p>Description for locale #{locale}</p>"
|
||||
investment.save!
|
||||
end
|
||||
end
|
||||
}.merge(translation_attributes))
|
||||
|
||||
add_image_to(investment) if Random.rand > 0.5
|
||||
end
|
||||
|
||||
26
db/migrate/20191102002206_install_audited.rb
Normal file
26
db/migrate/20191102002206_install_audited.rb
Normal file
@@ -0,0 +1,26 @@
|
||||
class InstallAudited < ActiveRecord::Migration[5.0]
|
||||
def change
|
||||
create_table :audits, force: true do |t|
|
||||
t.column :auditable_id, :integer
|
||||
t.column :auditable_type, :string
|
||||
t.column :associated_id, :integer
|
||||
t.column :associated_type, :string
|
||||
t.column :user_id, :integer
|
||||
t.column :user_type, :string
|
||||
t.column :username, :string
|
||||
t.column :action, :string
|
||||
t.column :audited_changes, :jsonb
|
||||
t.column :version, :integer, default: 0
|
||||
t.column :comment, :string
|
||||
t.column :remote_address, :string
|
||||
t.column :request_uuid, :string
|
||||
t.column :created_at, :datetime
|
||||
end
|
||||
|
||||
add_index :audits, [:auditable_type, :auditable_id, :version], name: "auditable_index"
|
||||
add_index :audits, [:associated_type, :associated_id], name: "associated_index"
|
||||
add_index :audits, [:user_id, :user_type], name: "user_index"
|
||||
add_index :audits, :request_uuid
|
||||
add_index :audits, :created_at
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,13 @@
|
||||
class DropBudgetInvestmentChangeLogs < ActiveRecord::Migration[5.0]
|
||||
def change
|
||||
drop_table :budget_investment_change_logs do |t|
|
||||
t.integer :investment_id
|
||||
t.integer :author_id
|
||||
t.string :field
|
||||
t.string :new_value
|
||||
t.string :old_value
|
||||
|
||||
t.timestamps null: false
|
||||
end
|
||||
end
|
||||
end
|
||||
34
db/schema.rb
34
db/schema.rb
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20191101183155) do
|
||||
ActiveRecord::Schema.define(version: 20191102002238) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@@ -84,6 +84,28 @@ ActiveRecord::Schema.define(version: 20191101183155) do
|
||||
t.index ["visit_id"], name: "index_ahoy_events_on_visit_id", using: :btree
|
||||
end
|
||||
|
||||
create_table "audits", force: :cascade do |t|
|
||||
t.integer "auditable_id"
|
||||
t.string "auditable_type"
|
||||
t.integer "associated_id"
|
||||
t.string "associated_type"
|
||||
t.integer "user_id"
|
||||
t.string "user_type"
|
||||
t.string "username"
|
||||
t.string "action"
|
||||
t.jsonb "audited_changes"
|
||||
t.integer "version", default: 0
|
||||
t.string "comment"
|
||||
t.string "remote_address"
|
||||
t.string "request_uuid"
|
||||
t.datetime "created_at"
|
||||
t.index ["associated_type", "associated_id"], name: "associated_index", using: :btree
|
||||
t.index ["auditable_type", "auditable_id", "version"], name: "auditable_index", using: :btree
|
||||
t.index ["created_at"], name: "index_audits_on_created_at", using: :btree
|
||||
t.index ["request_uuid"], name: "index_audits_on_request_uuid", using: :btree
|
||||
t.index ["user_id", "user_type"], name: "user_index", using: :btree
|
||||
end
|
||||
|
||||
create_table "banner_sections", force: :cascade do |t|
|
||||
t.integer "banner_id"
|
||||
t.integer "web_section_id"
|
||||
@@ -203,16 +225,6 @@ ActiveRecord::Schema.define(version: 20191101183155) do
|
||||
t.index ["group_id"], name: "index_budget_headings_on_group_id", using: :btree
|
||||
end
|
||||
|
||||
create_table "budget_investment_change_logs", force: :cascade do |t|
|
||||
t.integer "investment_id"
|
||||
t.integer "author_id"
|
||||
t.string "field"
|
||||
t.string "new_value"
|
||||
t.string "old_value"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
create_table "budget_investment_milestone_translations", force: :cascade do |t|
|
||||
t.integer "budget_investment_milestone_id", null: false
|
||||
t.string "locale", null: false
|
||||
|
||||
38
spec/features/admin/audits_spec.rb
Normal file
38
spec/features/admin/audits_spec.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe "Admin change log" do
|
||||
let(:administrator) { create(:administrator, user: create(:user, username: "Ana")) }
|
||||
before { login_as(administrator.user) }
|
||||
|
||||
context "Investments Participatory Budgets" do
|
||||
scenario "Changes" do
|
||||
investment = create(:budget_investment, title: "Good old times")
|
||||
|
||||
visit admin_budget_budget_investment_path(investment.budget, investment)
|
||||
|
||||
expect(page).to have_content "There are no changes logged"
|
||||
|
||||
click_link "Edit"
|
||||
fill_in "Title", with: "Modern times"
|
||||
click_button "Update"
|
||||
|
||||
expect(page).not_to have_content "There are no changes logged"
|
||||
expect(page).to have_content "Change Log"
|
||||
|
||||
within("#audits thead") do
|
||||
expect(page).to have_content "Field"
|
||||
expect(page).to have_content "Old Value"
|
||||
expect(page).to have_content "New Value"
|
||||
expect(page).to have_content "Edited at"
|
||||
expect(page).to have_content "Edited by"
|
||||
end
|
||||
|
||||
within("#audits tbody") do
|
||||
expect(page).to have_content "Title"
|
||||
expect(page).to have_content "Good old times"
|
||||
expect(page).to have_content "Modern times"
|
||||
expect(page).to have_content "Ana"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,68 +0,0 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe "Admin change log" do
|
||||
let(:budget) { create(:budget) }
|
||||
let(:administrator) do
|
||||
create(:administrator, user: create(:user, username: "Ana", email: "ana@admins.org"))
|
||||
end
|
||||
|
||||
context "Investments Participatory Budgets" do
|
||||
before do
|
||||
login_as(create(:administrator).user)
|
||||
end
|
||||
|
||||
scenario "No changes" do
|
||||
budget_investment = create(:budget_investment,
|
||||
:unfeasible,
|
||||
unfeasibility_explanation: "It is impossible",
|
||||
price: 1234,
|
||||
price_first_year: 1000,
|
||||
administrator: administrator)
|
||||
|
||||
visit admin_budget_budget_investments_path(budget_investment.budget)
|
||||
|
||||
click_link budget_investment.title
|
||||
|
||||
expect(page).to have_content(budget_investment.title)
|
||||
expect(page).to have_content(budget_investment.description)
|
||||
expect(page).to have_content(budget_investment.author.name)
|
||||
expect(page).to have_content(budget_investment.heading.name)
|
||||
expect(page).to have_content("There are not changes logged")
|
||||
end
|
||||
|
||||
scenario "Changes" do
|
||||
budget_investment = create(:budget_investment,
|
||||
:unfeasible,
|
||||
unfeasibility_explanation: "It is impossible",
|
||||
price: 1234,
|
||||
price_first_year: 1000,
|
||||
administrator: administrator)
|
||||
|
||||
visit admin_budget_budget_investments_path(budget_investment.budget)
|
||||
|
||||
click_link budget_investment.title
|
||||
|
||||
expect(page).to have_content(budget_investment.title)
|
||||
expect(page).to have_content(budget_investment.description)
|
||||
expect(page).to have_content(budget_investment.author.name)
|
||||
expect(page).to have_content(budget_investment.heading.name)
|
||||
expect(page).to have_content("There are not changes logged")
|
||||
|
||||
budget_investment.update!(title: "test")
|
||||
|
||||
visit admin_budget_budget_investments_path(budget_investment.budget)
|
||||
|
||||
click_link budget_investment.title
|
||||
|
||||
expect(page).not_to have_content("There are not changes logged")
|
||||
expect(page).to have_content("Change Log")
|
||||
expect(page).to have_content("Title")
|
||||
expect(page).to have_content("test")
|
||||
expect(page).to have_content("Field")
|
||||
expect(page).to have_content("Old Value")
|
||||
expect(page).to have_content("New Value")
|
||||
expect(page).to have_content("Edited at")
|
||||
expect(page).to have_content("Edited by")
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user