Merge pull request #4028 from consul/rails5.2_compatibility

Add Rails 5.2 compatibility
This commit is contained in:
Javier Martín
2020-07-14 13:40:30 +02:00
committed by GitHub
37 changed files with 78 additions and 338 deletions

View File

@@ -40,7 +40,7 @@ gem "omniauth-twitter", "~> 1.4.0"
gem "paperclip", "~> 5.2.1"
gem "paranoia", "~> 2.4.2"
gem "pg", "~> 0.21.0"
gem "pg_search", "~> 2.0.1"
gem "pg_search", "~> 2.3.0"
gem "puma", "~> 4.3.5"
gem "recipient_interceptor", "~> 0.2.0"
gem "redcarpet", "~> 3.4.0"

View File

@@ -396,10 +396,9 @@ GEM
parser (2.7.1.3)
ast (~> 2.4.0)
pg (0.21.0)
pg_search (2.0.1)
pg_search (2.3.0)
activerecord (>= 4.2)
activesupport (>= 4.2)
arel (>= 6)
public_suffix (4.0.1)
puma (4.3.5)
nio4r (~> 2.0)
@@ -665,7 +664,7 @@ DEPENDENCIES
paperclip (~> 5.2.1)
paranoia (~> 2.4.2)
pg (~> 0.21.0)
pg_search (~> 2.0.1)
pg_search (~> 2.3.0)
puma (~> 4.3.5)
rails (= 5.1.7)
rails-assets-leaflet!

View File

@@ -29,7 +29,7 @@ class GraphqlController < ApplicationController
private
def consul_schema
api_types = GraphQL::ApiTypesCreator.create(API_TYPE_DEFINITIONS)
api_types = GraphQL::ApiTypesCreator.create
query_type = GraphQL::QueryTypeCreator.create(api_types)
GraphQL::Schema.define do

View File

@@ -158,7 +158,7 @@ class ProposalsController < ApplicationController
.sort_by_confidence_score.limit(Setting["featured_proposals_number"])
if @featured_proposals.present?
set_featured_proposal_votes(@featured_proposals)
@resources = @resources.where("proposals.id NOT IN (?)", @featured_proposals.map(&:id))
@resources = @resources.where.not(id: @featured_proposals)
end
end
end

View File

@@ -96,7 +96,7 @@ class UsersController < ApplicationController
disabled_commentables << "Debate" unless Setting["process.debates"]
disabled_commentables << "Budget::Investment" unless Setting["process.budgets"]
if disabled_commentables.present?
all_user_comments.where("commentable_type NOT IN (?)", disabled_commentables)
all_user_comments.where.not(commentable_type: disabled_commentables)
else
all_user_comments
end

View File

@@ -1,3 +1,11 @@
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
def self.sample(count = 1)
if count == 1
reorder("RANDOM()").first
else
reorder("RANDOM()").limit(count)
end
end
end

View File

@@ -167,7 +167,7 @@ class Budget
ids += results.where(selected: true).pluck(:id) if params[:advanced_filters].include?("selected")
ids += results.undecided.pluck(:id) if params[:advanced_filters].include?("undecided")
ids += results.unfeasible.pluck(:id) if params[:advanced_filters].include?("unfeasible")
results = results.where("budget_investments.id IN (?)", ids) if ids.any?
results = results.where(id: ids) if ids.any?
results
end
@@ -194,7 +194,7 @@ class Budget
ids += Investment.where(heading_id: hid).order(confidence_score: :desc).limit(max_per_heading).pluck(:id)
end
results.where("budget_investments.id IN (?)", ids)
results.where(id: ids)
end
def self.search_by_title_or_id(title_or_id)

View File

@@ -45,9 +45,7 @@ class Community < ApplicationRecord
private
def users_who_commented
topics_ids = topics.pluck(:id)
query = "comments.commentable_id IN (?)and comments.commentable_type = 'Topic'"
User.by_comments(query, topics_ids)
User.by_comments(topics)
end
def users_who_topics_author

View File

@@ -2,7 +2,7 @@ module Searchable
extend ActiveSupport::Concern
included do
include PgSearch
include PgSearch::Model
include SearchCache
pg_search_scope :pg_search, ->(query) do

View File

@@ -31,6 +31,6 @@ class TagCloud
end
def table_name
resource_model.to_s.downcase.pluralize.gsub("::", "/")
resource_model.to_s.tableize.tr("/", "_")
end
end

View File

@@ -108,8 +108,10 @@ class User < ApplicationRecord
scope :active, -> { where(erased_at: nil) }
scope :erased, -> { where.not(erased_at: nil) }
scope :public_for_api, -> { all }
scope :by_comments, ->(query, topics_ids) { joins(:comments).where(query, topics_ids).distinct }
scope :by_authors, ->(author_ids) { where("users.id IN (?)", author_ids) }
scope :by_authors, ->(author_ids) { where(id: author_ids) }
scope :by_comments, ->(commentables) do
joins(:comments).where("comments.commentable": commentables).distinct
end
scope :by_username_email_or_document_number, ->(search_string) do
string = "%#{search_string}%"
where("username ILIKE ? OR email ILIKE ? OR document_number ILIKE ?", string, string, string)

View File

@@ -60,7 +60,6 @@ module Consul
config.after_initialize do
Globalize.set_fallbacks_to_all_available_locales
GraphQLApi::Loader.setup
end
config.assets.paths << Rails.root.join("app", "assets", "fonts")

View File

@@ -48,11 +48,9 @@ namespace :deploy do
after :updating, "rvm1:install:rvm"
after :updating, "rvm1:install:ruby"
after :updating, "install_bundler_gem"
before "deploy:migrate", "remove_local_census_records_duplicates"
after "deploy:migrate", "add_new_settings"
before :publishing, "smtp_ssl_and_delay_jobs_secrets"
after :publishing, "setup_puma"
after :published, "deploy:restart"
@@ -76,16 +74,6 @@ task :install_bundler_gem do
end
end
task :remove_local_census_records_duplicates do
on roles(:db) do
within release_path do
with rails_env: fetch(:rails_env) do
execute :rake, "local_census_records:remove_duplicates"
end
end
end
end
task :refresh_sitemap do
on roles(:app) do
within release_path do
@@ -116,49 +104,12 @@ task :execute_release_tasks do
end
end
desc "Create pid and socket folders needed by puma and convert unicorn sockets into symbolic links \
to the puma socket, so legacy nginx configurations pointing to the unicorn socket keep working"
desc "Create pid and socket folders needed by puma"
task :setup_puma do
on roles(:app) do
with rails_env: fetch(:rails_env) do
execute "mkdir -p #{shared_path}/tmp/sockets; true"
execute "mkdir -p #{shared_path}/tmp/pids; true"
if test("[ -e #{shared_path}/tmp/sockets/unicorn.sock ]")
execute "ln -sf #{shared_path}/tmp/sockets/puma.sock #{shared_path}/tmp/sockets/unicorn.sock; true"
end
if test("[ -e #{shared_path}/sockets/unicorn.sock ]")
execute "ln -sf #{shared_path}/tmp/sockets/puma.sock #{shared_path}/sockets/unicorn.sock; true"
end
end
end
end
task :smtp_ssl_and_delay_jobs_secrets do
on roles(:app) do
if test("[ -d #{current_path} ]")
within current_path do
with rails_env: fetch(:rails_env) do
tasks_file_path = "lib/tasks/secrets.rake"
shared_secrets_path = "#{shared_path}/config/secrets.yml"
unless test("[ -e #{current_path}/#{tasks_file_path} ]")
begin
unless test("[ -w #{shared_secrets_path} ]")
execute "sudo chown `whoami` #{shared_secrets_path}"
execute "chmod u+w #{shared_secrets_path}"
end
execute "cp #{release_path}/#{tasks_file_path} #{current_path}/#{tasks_file_path}"
execute :rake, "secrets:smtp_ssl_and_delay_jobs"
ensure
execute "rm #{current_path}/#{tasks_file_path}"
end
end
end
end
end
end
end

View File

@@ -37,10 +37,10 @@ module ActsAsTaggableOn
scope :public_for_api, -> do
where("(tags.kind IS NULL or tags.kind = ?) and tags.id in (?)",
"category",
Tagging.public_for_api.pluck("DISTINCT taggings.tag_id"))
Tagging.public_for_api.distinct.pluck("taggings.tag_id"))
end
include PgSearch
include PgSearch::Model
pg_search_scope :pg_search, against: :name,
using: {
@@ -79,7 +79,7 @@ module ActsAsTaggableOn
private
def custom_counter_field_name_for(taggable_type)
"#{taggable_type.underscore.pluralize}_count"
"#{taggable_type.tableize.tr("/", "_")}_count"
end
end
end

View File

@@ -1,11 +0,0 @@
module GraphQLApi
class Loader
def self.setup
if ActiveRecord::Base.connection.tables.any?
api_config = YAML.load_file("./config/api.yml")
GraphqlController.const_set "API_TYPE_DEFINITIONS",
GraphQL::ApiTypesCreator.parse_api_config_file(api_config)
end
end
end
end

View File

@@ -147,7 +147,7 @@ end
section "Marking investments as visible to valuators" do
(1..50).to_a.sample.times do
Budget::Investment.reorder("RANDOM()").first.update(visible_to_valuators: true)
Budget::Investment.sample.update(visible_to_valuators: true)
end
end

View File

@@ -19,7 +19,7 @@ section "Flagging Debates & Comments" do
end
section "Ignoring flags in Debates, comments & proposals" do
Debate.flagged.reorder("RANDOM()").limit(10).each(&:ignore_flag)
Comment.flagged.reorder("RANDOM()").limit(30).each(&:ignore_flag)
Proposal.flagged.reorder("RANDOM()").limit(10).each(&:ignore_flag)
Debate.flagged.sample(10).each(&:ignore_flag)
Comment.flagged.sample(30).each(&:ignore_flag)
Proposal.flagged.sample(10).each(&:ignore_flag)
end

View File

@@ -1,11 +1,11 @@
section "Hiding debates, comments & proposals" do
Comment.with_hidden.flagged.reorder("RANDOM()").limit(30).each(&:hide)
Debate.with_hidden.flagged.reorder("RANDOM()").limit(5).each(&:hide)
Proposal.with_hidden.flagged.reorder("RANDOM()").limit(10).each(&:hide)
Comment.with_hidden.flagged.sample(30).each(&:hide)
Debate.with_hidden.flagged.sample(5).each(&:hide)
Proposal.with_hidden.flagged.sample(10).each(&:hide)
end
section "Confirming hiding in debates, comments & proposals" do
Comment.only_hidden.flagged.reorder("RANDOM()").limit(10).each(&:confirm_hide)
Debate.only_hidden.flagged.reorder("RANDOM()").limit(5).each(&:confirm_hide)
Proposal.only_hidden.flagged.reorder("RANDOM()").limit(5).each(&:confirm_hide)
Comment.only_hidden.flagged.sample(10).each(&:confirm_hide)
Debate.only_hidden.flagged.sample(5).each(&:confirm_hide)
Proposal.only_hidden.flagged.sample(5).each(&:confirm_hide)
end

View File

@@ -4,10 +4,10 @@ section "Creating comment notifications" do
title: Faker::Lorem.sentence(3).truncate(60),
description: "<p>#{Faker::Lorem.paragraphs.join("</p><p>")}</p>",
tag_list: Tag.all.sample(3).join(","),
geozone: Geozone.reorder("RANDOM()").first,
geozone: Geozone.sample,
terms_of_service: "1")
comment = Comment.create!(user: User.reorder("RANDOM()").first,
comment = Comment.create!(user: User.sample,
body: Faker::Lorem.sentence,
commentable: debate)

View File

@@ -13,7 +13,7 @@ section "Creating polls" do
starts_at: 5.days.ago,
ends_at: 5.days.from_now,
geozone_restricted: true,
geozones: Geozone.reorder("RANDOM()").limit(3))
geozones: Geozone.sample(3))
Poll.create!(name: I18n.t("seeds.polls.recounting_poll"),
slug: I18n.t("seeds.polls.recounting_poll").parameterize,

View File

@@ -1,5 +1,5 @@
section "Voting Debates, Proposals & Comments" do
not_org_users = User.where(["users.id NOT IN(?)", User.organizations.pluck(:id)])
not_org_users = User.where.not(id: User.organizations)
100.times do
voter = not_org_users.level_two_or_three_verified.all.sample
vote = [true, false].sample

View File

@@ -0,0 +1,9 @@
class RenameColumnsWithSlashCharacters < ActiveRecord::Migration[5.1]
def change
change_table :tags do |t|
t.rename :"budget/investments_count", :budget_investments_count
t.rename :"legislation/proposals_count", :legislation_proposals_count
t.rename :"legislation/processes_count", :legislation_processes_count
end
end
end

View File

@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20191108173350) do
ActiveRecord::Schema.define(version: 20200519120717) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -1407,12 +1407,12 @@ ActiveRecord::Schema.define(version: 20191108173350) do
t.integer "debates_count", default: 0
t.integer "proposals_count", default: 0
t.string "kind"
t.integer "budget/investments_count", default: 0
t.integer "legislation/proposals_count", default: 0
t.integer "legislation/processes_count", default: 0
t.integer "budget_investments_count", default: 0
t.integer "legislation_proposals_count", default: 0
t.integer "legislation_processes_count", default: 0
t.index ["debates_count"], name: "index_tags_on_debates_count"
t.index ["legislation/processes_count"], name: "index_tags_on_legislation/processes_count"
t.index ["legislation/proposals_count"], name: "index_tags_on_legislation/proposals_count"
t.index ["legislation_processes_count"], name: "index_tags_on_legislation_processes_count"
t.index ["legislation_proposals_count"], name: "index_tags_on_legislation_proposals_count"
t.index ["name"], name: "index_tags_on_name", unique: true
t.index ["proposals_count"], name: "index_tags_on_proposals_count"
end

View File

@@ -10,7 +10,7 @@ module GraphQL
string: GraphQL::STRING_TYPE
}.freeze
def self.create(api_types_definitions)
def self.create
created_types = {}
api_types_definitions.each do |model, info|
create_type(model, info[:fields], created_types)
@@ -18,6 +18,10 @@ module GraphQL
created_types
end
def self.api_types_definitions
@api_types_definitions ||= parse_api_config_file(YAML.load_file(Rails.root.join("config/api.yml")))
end
def self.type_kind(type)
if SCALAR_TYPES[type]
:scalar

View File

@@ -10,15 +10,4 @@ namespace :budgets do
Budget.last.email_unselected
end
end
desc "Update investments original_heading_id with current heading_id"
task set_original_heading_id: :environment do
ApplicationLogger.new.info "Setting original_heading_id to investments"
Budget::Investment.find_each do |investment|
unless investment.original_heading_id.present?
investment.update_column(:original_heading_id, investment.heading_id)
end
print "."
end
end
end

View File

@@ -1,13 +1,5 @@
namespace :consul do
desc "Runs tasks needed to upgrade to the latest version"
task execute_release_tasks: ["settings:rename_setting_keys",
"settings:add_new_settings",
"execute_release_1.1.0_tasks"]
desc "Runs tasks needed to upgrade from 1.0.0 to 1.1.0"
task "execute_release_1.1.0_tasks": [
"budgets:set_original_heading_id",
"migrations:valuation_taggings",
"migrations:budget_admins_and_valuators"
]
"settings:add_new_settings"]
end

View File

@@ -1,13 +0,0 @@
namespace :local_census_records do
desc "Remove duplicated records from database"
task remove_duplicates: :environment do
ids = LocalCensusRecord.group(:document_type, :document_number).pluck("MIN(id) as id")
duplicates = LocalCensusRecord.count - ids.size
if duplicates > 0
ApplicationLogger.new.info "Removing local census records duplicates"
LocalCensusRecord.where("id NOT IN (?)", ids).destroy_all
ApplicationLogger.new.info "Removed #{duplicates} records."
end
end
end

View File

@@ -1,20 +0,0 @@
namespace :migrations do
desc "Migrates context of valuation taggings"
task valuation_taggings: :environment do
ApplicationLogger.new.info "Updating valuation taggings context"
Tagging.where(context: "valuation").update_all(context: "valuation_tags")
end
desc "Migrates budget staff"
task budget_admins_and_valuators: :environment do
ApplicationLogger.new.info "Updating budget administrators and valuators"
Budget.find_each do |budget|
investments = budget.investments.with_hidden
budget.update!(
administrator_ids: investments.where.not(administrator: nil).distinct.pluck(:administrator_id),
valuator_ids: Budget::ValuatorAssignment.where(investment: investments).distinct.pluck(:valuator_id)
)
end
end
end

View File

@@ -1,29 +0,0 @@
namespace :secrets do
desc "Add SMTP, SSL and delay jobs settings to secrets.yml"
task smtp_ssl_and_delay_jobs: :environment do
current_settings = {
"mailer_delivery_method" => ActionMailer::Base.delivery_method,
"smtp_settings" => ActionMailer::Base.smtp_settings,
"force_ssl" => Rails.application.config.force_ssl,
"delay_jobs" => Delayed::Worker.delay_jobs
}
settings_to_add = current_settings.select do |name, _|
Rails.application.secrets[name].nil?
end
exit if settings_to_add.empty?
secrets = Rails.application.config.paths["config/secrets"].first
stream = Psych.parse_stream(File.read(secrets))
nodes = stream.children.first.children.first
environment_index = nodes.children.index do |child|
child.is_a?(Psych::Nodes::Scalar) && child.value == Rails.env
end
nodes.children[environment_index + 1].children.push(*Psych.parse(settings_to_add.to_yaml).children.first.children)
File.open(secrets, "w") { |file| file.write stream.to_yaml }
end
end

View File

@@ -45,12 +45,9 @@ class UserSegments
def self.not_supported_on_current_budget
author_ids(
User.where(
"id NOT IN (SELECT DISTINCT(voter_id) FROM votes"\
" WHERE votable_type = ? AND votes.votable_id IN (?))",
"Budget::Investment",
current_budget_investments.pluck(:id)
)
User.where.not(
id: Vote.select(:voter_id).where(votable: current_budget_investments).distinct
)
)
end

View File

@@ -38,12 +38,12 @@ describe PagesController do
describe "Not found pages" do
it "returns a 404 message" do
get :show, params: { id: "nonExistentPage" }
expect(response).to be_missing
expect(response).to be_not_found
end
it "returns a 404 message for a JavaScript request" do
get :show, params: { id: "nonExistentJavaScript.js" }
expect(response).to be_missing
expect(response).to be_not_found
end
end
end

View File

@@ -1,13 +1,15 @@
require "rails_helper"
describe GraphQL::QueryTypeCreator do
let(:api_type_definitions) do
{
ProposalNotification => { fields: { title: :string }},
Proposal => { fields: { id: :integer, title: :string }}
}
before do
allow(GraphQL::ApiTypesCreator).to receive(:api_types_definitions).and_return(
{
ProposalNotification => { fields: { title: :string }},
Proposal => { fields: { id: :integer, title: :string }}
}
)
end
let(:api_types) { GraphQL::ApiTypesCreator.create(api_type_definitions) }
let(:api_types) { GraphQL::ApiTypesCreator.create }
describe "::create" do
let(:query_type) { GraphQL::QueryTypeCreator.create(api_types) }

View File

@@ -1,6 +1,6 @@
require "rails_helper"
api_types = GraphQL::ApiTypesCreator.create(GraphqlController::API_TYPE_DEFINITIONS)
api_types = GraphQL::ApiTypesCreator.create
query_type = GraphQL::QueryTypeCreator.create(api_types)
ConsulSchema = GraphQL::Schema.define do
query query_type

View File

@@ -1,35 +0,0 @@
require "rails_helper"
describe Budget do
let(:run_rake_task) do
Rake::Task["budgets:set_original_heading_id"].reenable
Rake.application.invoke_task("budgets:set_original_heading_id")
end
it "sets attribute original_heading_id for existing investments" do
heading = create(:budget_heading)
investment = create(:budget_investment, heading: heading)
investment.update!(original_heading_id: nil)
expect(investment.original_heading_id).to equal(nil)
run_rake_task
investment.reload
expect(investment.original_heading_id).to equal(heading.id)
end
it "does not overwrite original_heading_id when already present" do
original_heading = create(:budget_heading)
new_heading = create(:budget_heading)
investment = create(:budget_investment, heading: original_heading)
investment.update!(heading: new_heading)
expect(investment.original_heading_id).to eq original_heading.id
run_rake_task
investment.reload
expect(investment.original_heading_id).to eq original_heading.id
end
end

View File

@@ -1,36 +0,0 @@
require "rails_helper"
require Rails.root.join("db", "migrate", "20190530082138_add_unique_index_to_local_census_records")
describe "LocalCensusRecord tasks" do
let(:run_rake_task) do
Rake::Task["local_census_records:remove_duplicates"].reenable
Rake.application.invoke_task("local_census_records:remove_duplicates")
end
describe "#remove_duplicates" do
around do |example|
ActiveRecord::Migration.suppress_messages do
example.run
end
end
before { AddUniqueIndexToLocalCensusRecords.new.down }
after { AddUniqueIndexToLocalCensusRecords.new.up }
it "Remove all duplicates keeping older records" do
record1 = create(:local_census_record, document_type: "1", document_number: "#DOCUMENT_NUMBER")
record2 = create(:local_census_record, document_type: "2", document_number: "#DOCUMENT_NUMBER")
dup_record1 = build(:local_census_record, document_type: "1", document_number: "#DOCUMENT_NUMBER")
dup_record1.save!(validate: false)
dup_record2 = build(:local_census_record, document_type: "2", document_number: "#DOCUMENT_NUMBER")
dup_record2.save!(validate: false)
record3 = create(:local_census_record, document_type: "3", document_number: "#DOCUMENT_NUMBER")
expect(LocalCensusRecord.count).to eq(5)
run_rake_task
expect(LocalCensusRecord.all).to match_array([record1, record2, record3])
end
end
end

View File

@@ -1,68 +0,0 @@
require "rails_helper"
describe "Migration tasks" do
describe "valuation_taggins" do
let(:run_rake_task) do
Rake::Task["migrations:valuation_taggings"].reenable
Rake.application.invoke_task("migrations:valuation_taggings")
end
it "updates taggings" do
valuation_tagging = create(:tagging, context: "valuation")
another_valuation_tagging = create(:tagging, context: "valuation")
valuation_tags_tagging = create(:tagging, context: "valuation_tags")
tags_tagging = create(:tagging)
run_rake_task
expect(valuation_tagging.reload.context).to eq "valuation_tags"
expect(another_valuation_tagging.reload.context).to eq "valuation_tags"
expect(valuation_tags_tagging.reload.context).to eq "valuation_tags"
expect(tags_tagging.reload.context).to eq "tags"
end
end
describe "budget_admins_and_valuators" do
let(:run_rake_task) do
Rake::Task["migrations:budget_admins_and_valuators"].reenable
Rake.application.invoke_task("migrations:budget_admins_and_valuators")
end
let(:old_budget) { create(:budget) }
let(:current_budget) { create(:budget) }
it "assigns administrators from existing investments" do
harold = create(:administrator)
john = create(:administrator)
root = create(:administrator)
create(:budget_investment, budget: old_budget, administrator: john)
create(:budget_investment, budget: old_budget, administrator: harold)
create(:budget_investment, budget: old_budget, administrator: nil)
create(:budget_investment, budget: current_budget, administrator: root)
run_rake_task
expect(old_budget.administrators).to match_array [john, harold]
expect(current_budget.administrators).to match_array [root]
end
it "assigns valuators from existing investments" do
tyrion = create(:valuator)
cersei = create(:valuator)
jaime = create(:valuator)
create(:budget_investment, budget: old_budget, valuators: [cersei])
create(:budget_investment, budget: old_budget, valuators: [jaime, cersei])
create(:budget_investment, budget: old_budget, valuators: [])
create(:budget_investment, budget: current_budget, valuators: [tyrion, jaime])
run_rake_task
expect(old_budget.valuators).to match_array [cersei, jaime]
expect(current_budget.valuators).to match_array [tyrion, jaime]
end
end
end

View File

@@ -13,11 +13,13 @@ RSpec.describe Community, type: :model do
community = proposal.community
user1 = create(:user)
user2 = create(:user)
user3 = create(:user)
topic1 = create(:topic, community: community, author: user1)
create(:comment, commentable: topic1, author: user1)
create(:comment, commentable: topic1, author: user2)
create(:topic, community: community, author: user2)
create(:comment, commentable: proposal, author: user3)
expect(community.participants).to match_array [user1, user2, proposal.author]
end