From 05aa48e70a67ee256b819f11b37623628cd67983 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 21 Feb 2019 22:43:07 +0100 Subject: [PATCH 01/33] Add pg_search gem --- Gemfile | 1 + Gemfile.lock | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/Gemfile b/Gemfile index e034724ba..497d90e7a 100644 --- a/Gemfile +++ b/Gemfile @@ -18,6 +18,7 @@ gem 'kaminari', '~> 1.1.1' gem "simple_form", ">= 3.0.0" gem 'rollbar', '2.8.3' gem 'whenever', require: false +gem 'pg_search', '2.1.4' gem 'prawn', '~> 2.2.0' gem 'prawn-table', '~> 0.2.2' gem 'elasticsearch-model' diff --git a/Gemfile.lock b/Gemfile.lock index 1a521d77c..c93320b97 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -223,6 +223,9 @@ GEM ast (~> 2.4.0) pdf-core (0.7.0) pg (0.17.1) + pg_search (2.1.4) + activerecord (>= 4.2) + activesupport (>= 4.2) polyamorous (1.3.3) activerecord (>= 3.0) powerpack (0.1.1) @@ -424,6 +427,7 @@ DEPENDENCIES letter_opener (= 1.4.1) localeapp (= 2.1.1) pg (= 0.17.1) + pg_search (= 2.1.4) prawn (~> 2.2.0) prawn-table (~> 0.2.2) pundit (~> 2.0.0) From 0af66cdfe786477e72eb4e87b1c67116708345b3 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 21 Feb 2019 22:43:50 +0100 Subject: [PATCH 02/33] Upgrade bundler --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index c93320b97..6f524d157 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -457,4 +457,4 @@ RUBY VERSION ruby 2.3.0p0 BUNDLED WITH - 1.16.2 + 1.17.0 From 6fd92f192a5479808ec1ceeb6d71824dade2c83e Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 21 Feb 2019 22:51:42 +0100 Subject: [PATCH 03/33] Remove elasticsearch and use pg_search --- .travis.yml | 4 -- Gemfile | 2 - Gemfile.lock | 17 ------ app/controllers/members_controller.rb | 5 -- app/controllers/posts_controller.rb | 39 ++++++-------- app/models/member.rb | 12 ----- app/models/post.rb | 62 ++-------------------- config/initializers/elasticsearch.rb | 3 -- lib/tasks/elasticsearch.rake | 1 - spec/controllers/offers_controller_spec.rb | 12 ----- 10 files changed, 19 insertions(+), 138 deletions(-) delete mode 100644 config/initializers/elasticsearch.rb delete mode 100644 lib/tasks/elasticsearch.rake diff --git a/.travis.yml b/.travis.yml index 730632329..95c06230b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,11 +10,7 @@ before_script: - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter - chmod +x ./cc-test-reporter - ./cc-test-reporter before-build - # allow elasticsearch to be ready - https://docs.travis-ci.com/user/database-setup/#ElasticSearch - - sleep 10 after_script: - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT -services: - - elasticsearch addons: chrome: stable diff --git a/Gemfile b/Gemfile index 497d90e7a..09cc1803f 100644 --- a/Gemfile +++ b/Gemfile @@ -21,8 +21,6 @@ gem 'whenever', require: false gem 'pg_search', '2.1.4' gem 'prawn', '~> 2.2.0' gem 'prawn-table', '~> 0.2.2' -gem 'elasticsearch-model' -gem 'elasticsearch-rails' gem 'skylight' gem 'sidekiq', '5.1.3' gem 'sidekiq-cron', '0.6.3' diff --git a/Gemfile.lock b/Gemfile.lock index 6f524d157..a511eea11 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -124,19 +124,6 @@ GEM dotenv-rails (2.7.1) dotenv (= 2.7.1) railties (>= 3.2, < 6.1) - elasticsearch (1.0.8) - elasticsearch-api (= 1.0.7) - elasticsearch-transport (= 1.0.7) - elasticsearch-api (1.0.7) - multi_json - elasticsearch-model (0.1.7) - activesupport (> 3) - elasticsearch (> 0.4) - hashie - elasticsearch-rails (0.1.7) - elasticsearch-transport (1.0.7) - faraday - multi_json erubi (1.7.1) erubis (2.7.0) et-orbi (1.1.2) @@ -157,7 +144,6 @@ GEM has_scope (0.6.0) actionpack (>= 3.2, < 5) activesupport (>= 3.2, < 5) - hashie (3.4.1) hstore_translate (1.0.0) activerecord (>= 3.1.0) http-cookie (1.0.3) @@ -209,7 +195,6 @@ GEM mini_portile2 (2.3.0) minitest (5.11.3) multi_json (1.11.2) - multipart-post (2.0.0) net-scp (1.2.1) net-ssh (>= 2.6.5) net-ssh (2.9.2) @@ -415,8 +400,6 @@ DEPENDENCIES database_cleaner (= 1.6.2) devise (~> 4.5.0) dotenv-rails (~> 2.7.1) - elasticsearch-model - elasticsearch-rails fabrication faker (~> 1.9) has_scope diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index 5545f4186..d8dff153d 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -20,11 +20,6 @@ def toggle_manager def toggle_active find_member @member.toggle(:active).save! - if @member.active - @member.add_all_posts_to_index - else - @member.remove_all_posts_from_index - end respond_to do |format| format.json { head :ok } format.html { redirect_to :back } diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index a74db794b..55fe2d32e 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -4,31 +4,22 @@ class PostsController < ApplicationController has_scope :by_organization, as: :org def index - if (query = params[:q]).present? - # match query term on fields - must = [ { multi_match: { - query: query.to_s, - type: "phrase_prefix", - fields: ["title^2", "description", "tags^2"] - } } ] - if current_organization.present? - # filter by organization - must << { term: { organization_id: { value: current_organization.id } } } - end - posts = model.__elasticsearch__.search( - query: { - bool: { - must: must - } - } - ).page(params[:page]).per(25).records - else - posts = model.active.of_active_members - if current_organization.present? - posts = posts.merge(current_organization.posts) - end - posts = apply_scopes(posts).page(params[:page]).per(25) + context = model.active.of_active_members + if current_organization.present? + context = context.where( + organization_id: current_organization.id + ) end + + posts = if (query = params[:q]).present? + context. + search_by_query(query). + page(params[:page]). + per(25) + else + apply_scopes(context).page(params[:page]).per(25) + end + instance_variable_set("@#{resources}", posts) end diff --git a/app/models/member.rb b/app/models/member.rb index 6e5381860..47739daa0 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -44,18 +44,6 @@ def display_id member_uid end - def remove_all_posts_from_index - Post.with_member.where("members.id = ?", self.id).find_each do |post| - post.delete_document - end - end - - def add_all_posts_to_index - Post.with_member.where("members.id = ?", self.id).find_each do |post| - post.update_or_delete_document(self) - end - end - def assign_registration_number self.member_uid ||= organization.next_reg_number_seq end diff --git a/app/models/post.rb b/app/models/post.rb index 485f0f319..85f0c02e3 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -1,40 +1,10 @@ -require 'elasticsearch/model' - class Post < ActiveRecord::Base include Taggable + include PgSearch - # Elasticsearch::Model doesn't work well with STI, so - # include it in subclasses directly. - def self.inherited(child) - super - - child.instance_eval do - include Elasticsearch::Model - - after_commit :index_document, on: :create - after_commit :update_or_delete_document, on: :update - after_commit :delete_document, on: :destroy - - settings( - analysis: { - analyzer: { - normal: { - tokenizer: "standard", - # lowercase, unaccent - filter: %w[lowercase asciifolding] - } - } - } - ) do - mapping do - indexes :title, analyzer: "normal" - indexes :description, analyzer: "normal" - indexes :tags - indexes :organization_id, type: :integer - end - end - end - end + pg_search_scope :search_by_query, + :against => [:title, :description, :tags], + :ignoring => :accents attr_reader :member_id @@ -72,30 +42,6 @@ def self.inherited(child) validates :category, presence: true validates :title, presence: true - def index_document - __elasticsearch__.index_document - end - - # pass member when doing bulk things - def update_or_delete_document(member = nil) - member ||= self.member - if active && member.try(:active) - begin - __elasticsearch__.update_document - rescue # document was not in the index. TODO: more specifi exception class - __elasticsearch__.index_document - end - else - __elasticsearch__.delete_document - end - rescue # document was not in the index. TODO: more specifi exception class - end - - def delete_document - __elasticsearch__.delete_document - rescue # document was not in the index. TODO: more specifi exception class - end - def as_indexed_json(*) as_json(only: [:title, :description, :tags, :organization_id]) end diff --git a/config/initializers/elasticsearch.rb b/config/initializers/elasticsearch.rb deleted file mode 100644 index 4f8d88b9e..000000000 --- a/config/initializers/elasticsearch.rb +++ /dev/null @@ -1,3 +0,0 @@ -if ENV["ELASTICSEARCH_URL"].present? - Elasticsearch::Model.client = Elasticsearch::Client.new host: ENV["ELASTICSEARCH_URL"] -end diff --git a/lib/tasks/elasticsearch.rake b/lib/tasks/elasticsearch.rake deleted file mode 100644 index 744fd91a7..000000000 --- a/lib/tasks/elasticsearch.rake +++ /dev/null @@ -1 +0,0 @@ -require 'elasticsearch/rails/tasks/import' diff --git a/spec/controllers/offers_controller_spec.rb b/spec/controllers/offers_controller_spec.rb index 4f1db8ecf..3757f1fa7 100644 --- a/spec/controllers/offers_controller_spec.rb +++ b/spec/controllers/offers_controller_spec.rb @@ -36,23 +36,11 @@ end describe "GET #index (search)" do - before do - Offer.__elasticsearch__.create_index!(force: true) - - # Import any already existing model into the index - # for instance the ones that have been created in upper - # `let!` or `before` blocks - Offer.__elasticsearch__.import(force: true, refresh: true) - end - it "populates an array of offers" do login(another_member.user) get "index", q: offer.title.split(/\s/).first - # @offers is a wrapper from Elasticsearch. It's iterator-equivalent to - # the underlying query from the database. - expect(assigns(:offers)).to be_a Elasticsearch::Model::Response::Records expect(assigns(:offers).size).to eq 1 expect(assigns(:offers)[0]).to eq offer expect(assigns(:offers).to_a).to eq([offer]) From 8d8b2be48b79448853eb743de03ac367a712680e Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Thu, 7 Mar 2019 23:29:47 +0100 Subject: [PATCH 04/33] Enable partial word searches in pg_search Doc: https://github.com/Casecommons/pg_search#prefix-postgresql-84-and-newer-only --- app/models/post.rb | 7 +++++-- spec/controllers/offers_controller_spec.rb | 10 ++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/app/models/post.rb b/app/models/post.rb index 85f0c02e3..644ab6164 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -3,8 +3,11 @@ class Post < ActiveRecord::Base include PgSearch pg_search_scope :search_by_query, - :against => [:title, :description, :tags], - :ignoring => :accents + against: [:title, :description, :tags], + ignoring: :accents, + using: { + tsearch: { prefix: true } + } attr_reader :member_id diff --git a/spec/controllers/offers_controller_spec.rb b/spec/controllers/offers_controller_spec.rb index 3757f1fa7..cca4c262c 100644 --- a/spec/controllers/offers_controller_spec.rb +++ b/spec/controllers/offers_controller_spec.rb @@ -36,15 +36,21 @@ end describe "GET #index (search)" do - it "populates an array of offers" do - login(another_member.user) + before { login(another_member.user) } + it "populates an array of offers" do get "index", q: offer.title.split(/\s/).first expect(assigns(:offers).size).to eq 1 expect(assigns(:offers)[0]).to eq offer expect(assigns(:offers).to_a).to eq([offer]) end + + it "allows to search by partial word" do + get :index, q: offer.title.split(/\s/).first[0..-2] + + expect(assigns(:offers)).to include offer + end end describe 'GET #show' do From aab779c2ca2337476ffbe0029b391b660beebe40 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Fri, 24 May 2019 00:58:42 +0200 Subject: [PATCH 05/33] Add tsvector column, trigger, index and unaccent extension --- app/models/post.rb | 5 ++- ...90523213421_add_tsvector_column_to_post.rb | 32 +++++++++++++++++++ ...0190523225323_enable_unaccent_extension.rb | 9 ++++++ db/schema.rb | 5 ++- 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20190523213421_add_tsvector_column_to_post.rb create mode 100644 db/migrate/20190523225323_enable_unaccent_extension.rb diff --git a/app/models/post.rb b/app/models/post.rb index 644ab6164..54711fef9 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -6,7 +6,10 @@ class Post < ActiveRecord::Base against: [:title, :description, :tags], ignoring: :accents, using: { - tsearch: { prefix: true } + tsearch: { + prefix: true, + tsvector_column: 'tsv' + } } attr_reader :member_id diff --git a/db/migrate/20190523213421_add_tsvector_column_to_post.rb b/db/migrate/20190523213421_add_tsvector_column_to_post.rb new file mode 100644 index 000000000..fe124d235 --- /dev/null +++ b/db/migrate/20190523213421_add_tsvector_column_to_post.rb @@ -0,0 +1,32 @@ +class AddTsvectorColumnToPost < ActiveRecord::Migration + def up + execute <<-SQL + ALTER TABLE posts ADD COLUMN tsv tsvector; + + CREATE FUNCTION posts_trigger() RETURNS trigger AS $$ + begin + new.tsv := + to_tsvector('simple', unaccent(coalesce(new.title::text, ''))) || + to_tsvector('simple', unaccent(coalesce(new.description::text, ''))) || + to_tsvector('simple', unaccent(coalesce(new.tags::text, ''))); + return new; + end + $$ LANGUAGE plpgsql; + + CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE + ON posts FOR EACH ROW EXECUTE PROCEDURE posts_trigger(); + SQL + + add_index :posts, :tsv, using: "gin" + end + + def down + execute <<-SQL + DROP TRIGGER tsvectorupdate ON posts; + DROP FUNCTION posts_trigger(); + SQL + + remove_index :posts, :tsv + remove_column :posts, :tsv + end +end diff --git a/db/migrate/20190523225323_enable_unaccent_extension.rb b/db/migrate/20190523225323_enable_unaccent_extension.rb new file mode 100644 index 000000000..d5dcc420f --- /dev/null +++ b/db/migrate/20190523225323_enable_unaccent_extension.rb @@ -0,0 +1,9 @@ +class EnableUnaccentExtension < ActiveRecord::Migration + def up + enable_extension "unaccent" + end + + def down + disable_extension "unaccent" + end +end diff --git a/db/schema.rb b/db/schema.rb index bfcd9e381..3adbc2d2f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,12 +11,13 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20190412163011) do +ActiveRecord::Schema.define(version: 20190523225323) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" enable_extension "hstore" enable_extension "pg_trgm" + enable_extension "unaccent" create_table "accounts", force: :cascade do |t| t.integer "accountable_id" @@ -147,11 +148,13 @@ t.integer "organization_id" t.boolean "active", default: true t.boolean "is_group", default: false + t.tsvector "tsv" end add_index "posts", ["category_id"], name: "index_posts_on_category_id", using: :btree add_index "posts", ["organization_id"], name: "index_posts_on_organization_id", using: :btree add_index "posts", ["tags"], name: "index_posts_on_tags", using: :gin + add_index "posts", ["tsv"], name: "index_posts_on_tsv", using: :gin add_index "posts", ["user_id"], name: "index_posts_on_user_id", using: :btree create_table "push_notifications", force: :cascade do |t| From 3b4a65631a83103c85fb7b141753b4043c065ed3 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Fri, 24 May 2019 17:18:44 +0200 Subject: [PATCH 06/33] Damn conflicts! --- Gemfile.lock | 2 -- 1 file changed, 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index a511eea11..173fbbb20 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -132,8 +132,6 @@ GEM fabrication (2.11.3) faker (1.9.3) i18n (>= 0.7) - faraday (0.9.1) - multipart-post (>= 1.2, < 3) ffi (1.10.0) formtastic (3.1.5) actionpack (>= 3.2.13) From e09469ce1aae16b0728fdeb3c3f86ecbdd61217d Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Fri, 24 May 2019 18:19:21 +0200 Subject: [PATCH 07/33] Use SQL for schema instead of Ruby --- config/application.rb | 4 + db/schema.rb | 226 -------- db/structure.sql | 1141 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1145 insertions(+), 226 deletions(-) delete mode 100644 db/schema.rb create mode 100644 db/structure.sql diff --git a/config/application.rb b/config/application.rb index 4bba4fc1b..4edfc6c1d 100644 --- a/config/application.rb +++ b/config/application.rb @@ -35,5 +35,9 @@ class Application < Rails::Application # ActiveJob configuration config.active_job.queue_adapter = :sidekiq + + # Use db/structure.sql with SQL as schema format + # This is needed to store in the schema SQL statements not covered by the ORM + config.active_record.schema_format = :sql end end diff --git a/db/schema.rb b/db/schema.rb deleted file mode 100644 index 3adbc2d2f..000000000 --- a/db/schema.rb +++ /dev/null @@ -1,226 +0,0 @@ -# encoding: UTF-8 -# This file is auto-generated from the current state of the database. Instead -# of editing this file, please use the migrations feature of Active Record to -# incrementally modify your database, and then regenerate this schema definition. -# -# Note that this schema.rb definition is the authoritative source for your -# database schema. If you need to create the application database on another -# system, you should be using db:schema:load, not running all the migrations -# from scratch. The latter is a flawed and unsustainable approach (the more migrations -# you'll amass, the slower it'll run and the greater likelihood for issues). -# -# It's strongly recommended that you check this file into your version control system. - -ActiveRecord::Schema.define(version: 20190523225323) do - - # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" - enable_extension "hstore" - enable_extension "pg_trgm" - enable_extension "unaccent" - - create_table "accounts", force: :cascade do |t| - t.integer "accountable_id" - t.string "accountable_type" - t.integer "balance", default: 0 - t.integer "max_allowed_balance" - t.integer "min_allowed_balance" - t.boolean "flagged" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "organization_id" - end - - add_index "accounts", ["accountable_type", "accountable_id"], name: "index_accounts_on_accountable_type_and_accountable_id", using: :btree - add_index "accounts", ["organization_id"], name: "index_accounts_on_organization_id", using: :btree - - create_table "active_admin_comments", force: :cascade do |t| - t.string "namespace" - t.text "body" - t.string "resource_id", null: false - t.string "resource_type", null: false - t.integer "author_id" - t.string "author_type" - t.datetime "created_at" - t.datetime "updated_at" - end - - add_index "active_admin_comments", ["author_type", "author_id"], name: "index_active_admin_comments_on_author_type_and_author_id", using: :btree - add_index "active_admin_comments", ["namespace"], name: "index_active_admin_comments_on_namespace", using: :btree - add_index "active_admin_comments", ["resource_type", "resource_id"], name: "index_active_admin_comments_on_resource_type_and_resource_id", using: :btree - - create_table "categories", force: :cascade do |t| - t.datetime "created_at" - t.datetime "updated_at" - t.hstore "name_translations" - end - - create_table "device_tokens", force: :cascade do |t| - t.integer "user_id", null: false - t.string "token", null: false - t.datetime "created_at" - t.datetime "updated_at" - end - - add_index "device_tokens", ["user_id", "token"], name: "index_device_tokens_on_user_id_and_token", unique: true, using: :btree - - create_table "documents", force: :cascade do |t| - t.integer "documentable_id" - t.string "documentable_type" - t.text "title" - t.text "content" - t.string "label" - t.datetime "created_at" - t.datetime "updated_at" - end - - add_index "documents", ["documentable_id", "documentable_type"], name: "index_documents_on_documentable_id_and_documentable_type", using: :btree - add_index "documents", ["label"], name: "index_documents_on_label", using: :btree - - create_table "events", force: :cascade do |t| - t.integer "action", null: false - t.integer "post_id" - t.integer "member_id" - t.integer "transfer_id" - t.datetime "created_at" - t.datetime "updated_at" - end - - add_index "events", ["member_id"], name: "index_events_on_member_id", where: "(member_id IS NOT NULL)", using: :btree - add_index "events", ["post_id"], name: "index_events_on_post_id", where: "(post_id IS NOT NULL)", using: :btree - add_index "events", ["transfer_id"], name: "index_events_on_transfer_id", where: "(transfer_id IS NOT NULL)", using: :btree - - create_table "members", force: :cascade do |t| - t.integer "user_id" - t.integer "organization_id" - t.boolean "manager" - t.datetime "created_at" - t.datetime "updated_at" - t.date "entry_date" - t.integer "member_uid" - t.boolean "active", default: true - end - - add_index "members", ["organization_id"], name: "index_members_on_organization_id", using: :btree - add_index "members", ["user_id"], name: "index_members_on_user_id", using: :btree - - create_table "movements", force: :cascade do |t| - t.integer "account_id" - t.integer "transfer_id" - t.integer "amount" - t.datetime "created_at" - t.datetime "updated_at" - end - - add_index "movements", ["account_id"], name: "index_movements_on_account_id", using: :btree - add_index "movements", ["transfer_id"], name: "index_movements_on_transfer_id", using: :btree - - create_table "organizations", force: :cascade do |t| - t.string "name", limit: 255, null: false - t.datetime "created_at" - t.datetime "updated_at" - t.integer "reg_number_seq" - t.string "theme" - t.string "email" - t.string "phone" - t.string "web" - t.text "public_opening_times" - t.text "description" - t.text "address" - t.string "neighborhood" - t.string "city" - t.string "domain" - end - - add_index "organizations", ["name"], name: "index_organizations_on_name", unique: true, using: :btree - - create_table "posts", force: :cascade do |t| - t.string "title" - t.string "type" - t.integer "category_id" - t.integer "user_id" - t.text "description" - t.date "start_on" - t.date "end_on" - t.datetime "created_at" - t.datetime "updated_at" - t.text "tags", array: true - t.integer "organization_id" - t.boolean "active", default: true - t.boolean "is_group", default: false - t.tsvector "tsv" - end - - add_index "posts", ["category_id"], name: "index_posts_on_category_id", using: :btree - add_index "posts", ["organization_id"], name: "index_posts_on_organization_id", using: :btree - add_index "posts", ["tags"], name: "index_posts_on_tags", using: :gin - add_index "posts", ["tsv"], name: "index_posts_on_tsv", using: :gin - add_index "posts", ["user_id"], name: "index_posts_on_user_id", using: :btree - - create_table "push_notifications", force: :cascade do |t| - t.integer "event_id", null: false - t.integer "device_token_id", null: false - t.datetime "processed_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "title", default: "", null: false - t.string "body", default: "", null: false - t.json "data", default: {}, null: false - end - - create_table "transfers", force: :cascade do |t| - t.integer "post_id" - t.text "reason" - t.integer "operator_id" - t.datetime "created_at" - t.datetime "updated_at" - end - - add_index "transfers", ["operator_id"], name: "index_transfers_on_operator_id", using: :btree - add_index "transfers", ["post_id"], name: "index_transfers_on_post_id", using: :btree - - create_table "users", force: :cascade do |t| - t.string "username", null: false - t.string "email", null: false - t.date "date_of_birth" - t.string "identity_document" - t.string "phone" - t.string "alt_phone" - t.text "address" - t.datetime "created_at" - t.datetime "updated_at" - t.datetime "deleted_at" - t.string "gender" - t.text "description" - t.boolean "active", default: true - t.datetime "terms_accepted_at" - t.string "encrypted_password", default: "", null: false - t.string "reset_password_token" - t.datetime "reset_password_sent_at" - t.datetime "remember_created_at" - t.integer "sign_in_count", default: 0 - t.datetime "current_sign_in_at" - t.datetime "last_sign_in_at" - t.string "current_sign_in_ip" - t.string "last_sign_in_ip" - t.string "confirmation_token" - t.datetime "confirmed_at" - t.datetime "confirmation_sent_at" - t.string "unconfirmed_email" - t.integer "failed_attempts", default: 0 - t.string "unlock_token" - t.datetime "locked_at" - t.string "locale", default: "es" - t.boolean "notifications", default: true - t.boolean "push_notifications", default: true, null: false - end - - add_index "users", ["email"], name: "index_users_on_email", using: :btree - - add_foreign_key "accounts", "organizations" - add_foreign_key "events", "members", name: "events_member_id_fkey" - add_foreign_key "events", "posts", name: "events_post_id_fkey" - add_foreign_key "events", "transfers", name: "events_transfer_id_fkey" - add_foreign_key "push_notifications", "device_tokens" - add_foreign_key "push_notifications", "events" -end diff --git a/db/structure.sql b/db/structure.sql new file mode 100644 index 000000000..5a2b8d516 --- /dev/null +++ b/db/structure.sql @@ -0,0 +1,1141 @@ +-- +-- PostgreSQL database dump +-- + +-- Dumped from database version 9.5.14 +-- Dumped by pg_dump version 9.5.14 + +SET statement_timeout = 0; +SET lock_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET client_min_messages = warning; +SET row_security = off; + +-- +-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: - +-- + +CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; + + +-- +-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: - +-- + +COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language'; + + +-- +-- Name: hstore; Type: EXTENSION; Schema: -; Owner: - +-- + +CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public; + + +-- +-- Name: EXTENSION hstore; Type: COMMENT; Schema: -; Owner: - +-- + +COMMENT ON EXTENSION hstore IS 'data type for storing sets of (key, value) pairs'; + + +-- +-- Name: pg_trgm; Type: EXTENSION; Schema: -; Owner: - +-- + +CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA public; + + +-- +-- Name: EXTENSION pg_trgm; Type: COMMENT; Schema: -; Owner: - +-- + +COMMENT ON EXTENSION pg_trgm IS 'text similarity measurement and index searching based on trigrams'; + + +-- +-- Name: unaccent; Type: EXTENSION; Schema: -; Owner: - +-- + +CREATE EXTENSION IF NOT EXISTS unaccent WITH SCHEMA public; + + +-- +-- Name: EXTENSION unaccent; Type: COMMENT; Schema: -; Owner: - +-- + +COMMENT ON EXTENSION unaccent IS 'text search dictionary that removes accents'; + + +-- +-- Name: posts_trigger(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.posts_trigger() RETURNS trigger + LANGUAGE plpgsql + AS $$ + begin + new.tsv := + to_tsvector('simple', unaccent(coalesce(new.title::text, ''))) || + to_tsvector('simple', unaccent(coalesce(new.description::text, ''))) || + to_tsvector('simple', unaccent(coalesce(new.tags::text, ''))); + return new; + end + $$; + + +SET default_tablespace = ''; + +SET default_with_oids = false; + +-- +-- Name: accounts; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.accounts ( + id integer NOT NULL, + accountable_id integer, + accountable_type character varying, + balance integer DEFAULT 0, + max_allowed_balance integer, + min_allowed_balance integer, + flagged boolean, + created_at timestamp without time zone, + updated_at timestamp without time zone, + organization_id integer +); + + +-- +-- Name: accounts_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.accounts_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: accounts_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.accounts_id_seq OWNED BY public.accounts.id; + + +-- +-- Name: active_admin_comments; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.active_admin_comments ( + id integer NOT NULL, + namespace character varying, + body text, + resource_id character varying NOT NULL, + resource_type character varying NOT NULL, + author_id integer, + author_type character varying, + created_at timestamp without time zone, + updated_at timestamp without time zone +); + + +-- +-- Name: active_admin_comments_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.active_admin_comments_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: active_admin_comments_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.active_admin_comments_id_seq OWNED BY public.active_admin_comments.id; + + +-- +-- Name: categories; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.categories ( + id integer NOT NULL, + created_at timestamp without time zone, + updated_at timestamp without time zone, + name_translations public.hstore +); + + +-- +-- Name: categories_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.categories_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: categories_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.categories_id_seq OWNED BY public.categories.id; + + +-- +-- Name: device_tokens; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.device_tokens ( + id integer NOT NULL, + user_id integer NOT NULL, + token character varying NOT NULL, + created_at timestamp without time zone, + updated_at timestamp without time zone +); + + +-- +-- Name: device_tokens_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.device_tokens_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: device_tokens_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.device_tokens_id_seq OWNED BY public.device_tokens.id; + + +-- +-- Name: documents; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.documents ( + id integer NOT NULL, + documentable_id integer, + documentable_type character varying, + title text, + content text, + label character varying, + created_at timestamp without time zone, + updated_at timestamp without time zone +); + + +-- +-- Name: documents_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.documents_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: documents_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.documents_id_seq OWNED BY public.documents.id; + + +-- +-- Name: events; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.events ( + id integer NOT NULL, + action integer NOT NULL, + post_id integer, + member_id integer, + transfer_id integer, + created_at timestamp without time zone, + updated_at timestamp without time zone +); + + +-- +-- Name: events_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.events_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: events_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.events_id_seq OWNED BY public.events.id; + + +-- +-- Name: members; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.members ( + id integer NOT NULL, + user_id integer, + organization_id integer, + manager boolean, + created_at timestamp without time zone, + updated_at timestamp without time zone, + entry_date date, + member_uid integer, + active boolean DEFAULT true +); + + +-- +-- Name: members_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.members_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: members_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.members_id_seq OWNED BY public.members.id; + + +-- +-- Name: movements; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.movements ( + id integer NOT NULL, + account_id integer, + transfer_id integer, + amount integer, + created_at timestamp without time zone, + updated_at timestamp without time zone +); + + +-- +-- Name: movements_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.movements_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: movements_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.movements_id_seq OWNED BY public.movements.id; + + +-- +-- Name: organizations; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.organizations ( + id integer NOT NULL, + name character varying(255) NOT NULL, + created_at timestamp without time zone, + updated_at timestamp without time zone, + reg_number_seq integer, + theme character varying, + email character varying, + phone character varying, + web character varying, + public_opening_times text, + description text, + address text, + neighborhood character varying, + city character varying, + domain character varying +); + + +-- +-- Name: organizations_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.organizations_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: organizations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.organizations_id_seq OWNED BY public.organizations.id; + + +-- +-- Name: posts; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.posts ( + id integer NOT NULL, + title character varying, + type character varying, + category_id integer, + user_id integer, + description text, + start_on date, + end_on date, + created_at timestamp without time zone, + updated_at timestamp without time zone, + tags text[], + organization_id integer, + active boolean DEFAULT true, + is_group boolean DEFAULT false, + tsv tsvector +); + + +-- +-- Name: posts_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.posts_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: posts_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.posts_id_seq OWNED BY public.posts.id; + + +-- +-- Name: push_notifications; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.push_notifications ( + id integer NOT NULL, + event_id integer NOT NULL, + device_token_id integer NOT NULL, + processed_at timestamp without time zone, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + title character varying DEFAULT ''::character varying NOT NULL, + body character varying DEFAULT ''::character varying NOT NULL, + data json DEFAULT '{}'::json NOT NULL +); + + +-- +-- Name: push_notifications_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.push_notifications_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: push_notifications_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.push_notifications_id_seq OWNED BY public.push_notifications.id; + + +-- +-- Name: schema_migrations; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.schema_migrations ( + version character varying NOT NULL +); + + +-- +-- Name: transfers; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.transfers ( + id integer NOT NULL, + post_id integer, + reason text, + operator_id integer, + created_at timestamp without time zone, + updated_at timestamp without time zone +); + + +-- +-- Name: transfers_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.transfers_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: transfers_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.transfers_id_seq OWNED BY public.transfers.id; + + +-- +-- Name: users; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.users ( + id integer NOT NULL, + username character varying NOT NULL, + email character varying NOT NULL, + date_of_birth date, + identity_document character varying, + phone character varying, + alt_phone character varying, + address text, + created_at timestamp without time zone, + updated_at timestamp without time zone, + deleted_at timestamp without time zone, + gender character varying, + description text, + active boolean DEFAULT true, + terms_accepted_at timestamp without time zone, + encrypted_password character varying DEFAULT ''::character varying NOT NULL, + reset_password_token character varying, + reset_password_sent_at timestamp without time zone, + remember_created_at timestamp without time zone, + sign_in_count integer DEFAULT 0, + current_sign_in_at timestamp without time zone, + last_sign_in_at timestamp without time zone, + current_sign_in_ip character varying, + last_sign_in_ip character varying, + confirmation_token character varying, + confirmed_at timestamp without time zone, + confirmation_sent_at timestamp without time zone, + unconfirmed_email character varying, + failed_attempts integer DEFAULT 0, + unlock_token character varying, + locked_at timestamp without time zone, + locale character varying DEFAULT 'es'::character varying, + notifications boolean DEFAULT true, + push_notifications boolean DEFAULT true NOT NULL +); + + +-- +-- Name: users_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.users_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: users_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.users_id_seq OWNED BY public.users.id; + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.accounts ALTER COLUMN id SET DEFAULT nextval('public.accounts_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.active_admin_comments ALTER COLUMN id SET DEFAULT nextval('public.active_admin_comments_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.categories ALTER COLUMN id SET DEFAULT nextval('public.categories_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.device_tokens ALTER COLUMN id SET DEFAULT nextval('public.device_tokens_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.documents ALTER COLUMN id SET DEFAULT nextval('public.documents_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.events ALTER COLUMN id SET DEFAULT nextval('public.events_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.members ALTER COLUMN id SET DEFAULT nextval('public.members_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.movements ALTER COLUMN id SET DEFAULT nextval('public.movements_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.organizations ALTER COLUMN id SET DEFAULT nextval('public.organizations_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.posts ALTER COLUMN id SET DEFAULT nextval('public.posts_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.push_notifications ALTER COLUMN id SET DEFAULT nextval('public.push_notifications_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.transfers ALTER COLUMN id SET DEFAULT nextval('public.transfers_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.users ALTER COLUMN id SET DEFAULT nextval('public.users_id_seq'::regclass); + + +-- +-- Name: accounts_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.accounts + ADD CONSTRAINT accounts_pkey PRIMARY KEY (id); + + +-- +-- Name: active_admin_comments_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.active_admin_comments + ADD CONSTRAINT active_admin_comments_pkey PRIMARY KEY (id); + + +-- +-- Name: categories_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.categories + ADD CONSTRAINT categories_pkey PRIMARY KEY (id); + + +-- +-- Name: device_tokens_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.device_tokens + ADD CONSTRAINT device_tokens_pkey PRIMARY KEY (id); + + +-- +-- Name: documents_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.documents + ADD CONSTRAINT documents_pkey PRIMARY KEY (id); + + +-- +-- Name: events_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.events + ADD CONSTRAINT events_pkey PRIMARY KEY (id); + + +-- +-- Name: members_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.members + ADD CONSTRAINT members_pkey PRIMARY KEY (id); + + +-- +-- Name: movements_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.movements + ADD CONSTRAINT movements_pkey PRIMARY KEY (id); + + +-- +-- Name: organizations_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.organizations + ADD CONSTRAINT organizations_pkey PRIMARY KEY (id); + + +-- +-- Name: posts_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.posts + ADD CONSTRAINT posts_pkey PRIMARY KEY (id); + + +-- +-- Name: push_notifications_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.push_notifications + ADD CONSTRAINT push_notifications_pkey PRIMARY KEY (id); + + +-- +-- Name: transfers_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.transfers + ADD CONSTRAINT transfers_pkey PRIMARY KEY (id); + + +-- +-- Name: users_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.users + ADD CONSTRAINT users_pkey PRIMARY KEY (id); + + +-- +-- Name: index_accounts_on_accountable_type_and_accountable_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_accounts_on_accountable_type_and_accountable_id ON public.accounts USING btree (accountable_type, accountable_id); + + +-- +-- Name: index_accounts_on_organization_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_accounts_on_organization_id ON public.accounts USING btree (organization_id); + + +-- +-- Name: index_active_admin_comments_on_author_type_and_author_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_active_admin_comments_on_author_type_and_author_id ON public.active_admin_comments USING btree (author_type, author_id); + + +-- +-- Name: index_active_admin_comments_on_namespace; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_active_admin_comments_on_namespace ON public.active_admin_comments USING btree (namespace); + + +-- +-- Name: index_active_admin_comments_on_resource_type_and_resource_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_active_admin_comments_on_resource_type_and_resource_id ON public.active_admin_comments USING btree (resource_type, resource_id); + + +-- +-- Name: index_device_tokens_on_user_id_and_token; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_device_tokens_on_user_id_and_token ON public.device_tokens USING btree (user_id, token); + + +-- +-- Name: index_documents_on_documentable_id_and_documentable_type; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_documents_on_documentable_id_and_documentable_type ON public.documents USING btree (documentable_id, documentable_type); + + +-- +-- Name: index_documents_on_label; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_documents_on_label ON public.documents USING btree (label); + + +-- +-- Name: index_events_on_member_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_events_on_member_id ON public.events USING btree (member_id) WHERE (member_id IS NOT NULL); + + +-- +-- Name: index_events_on_post_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_events_on_post_id ON public.events USING btree (post_id) WHERE (post_id IS NOT NULL); + + +-- +-- Name: index_events_on_transfer_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_events_on_transfer_id ON public.events USING btree (transfer_id) WHERE (transfer_id IS NOT NULL); + + +-- +-- Name: index_members_on_organization_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_members_on_organization_id ON public.members USING btree (organization_id); + + +-- +-- Name: index_members_on_user_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_members_on_user_id ON public.members USING btree (user_id); + + +-- +-- Name: index_movements_on_account_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_movements_on_account_id ON public.movements USING btree (account_id); + + +-- +-- Name: index_movements_on_transfer_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_movements_on_transfer_id ON public.movements USING btree (transfer_id); + + +-- +-- Name: index_organizations_on_name; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_organizations_on_name ON public.organizations USING btree (name); + + +-- +-- Name: index_posts_on_category_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_posts_on_category_id ON public.posts USING btree (category_id); + + +-- +-- Name: index_posts_on_organization_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_posts_on_organization_id ON public.posts USING btree (organization_id); + + +-- +-- Name: index_posts_on_tags; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_posts_on_tags ON public.posts USING gin (tags); + + +-- +-- Name: index_posts_on_tsv; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_posts_on_tsv ON public.posts USING gin (tsv); + + +-- +-- Name: index_posts_on_user_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_posts_on_user_id ON public.posts USING btree (user_id); + + +-- +-- Name: index_transfers_on_operator_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_transfers_on_operator_id ON public.transfers USING btree (operator_id); + + +-- +-- Name: index_transfers_on_post_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_transfers_on_post_id ON public.transfers USING btree (post_id); + + +-- +-- Name: index_users_on_email; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_users_on_email ON public.users USING btree (email); + + +-- +-- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX unique_schema_migrations ON public.schema_migrations USING btree (version); + + +-- +-- Name: tsvectorupdate; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE ON public.posts FOR EACH ROW EXECUTE PROCEDURE public.posts_trigger(); + + +-- +-- Name: events_member_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.events + ADD CONSTRAINT events_member_id_fkey FOREIGN KEY (member_id) REFERENCES public.members(id); + + +-- +-- Name: events_post_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.events + ADD CONSTRAINT events_post_id_fkey FOREIGN KEY (post_id) REFERENCES public.posts(id); + + +-- +-- Name: events_transfer_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.events + ADD CONSTRAINT events_transfer_id_fkey FOREIGN KEY (transfer_id) REFERENCES public.transfers(id); + + +-- +-- Name: fk_rails_1ceb778440; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.accounts + ADD CONSTRAINT fk_rails_1ceb778440 FOREIGN KEY (organization_id) REFERENCES public.organizations(id); + + +-- +-- Name: fk_rails_36fb6ef1a8; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.push_notifications + ADD CONSTRAINT fk_rails_36fb6ef1a8 FOREIGN KEY (device_token_id) REFERENCES public.device_tokens(id); + + +-- +-- Name: fk_rails_79a395b2d7; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.push_notifications + ADD CONSTRAINT fk_rails_79a395b2d7 FOREIGN KEY (event_id) REFERENCES public.events(id); + + +-- +-- PostgreSQL database dump complete +-- + +SET search_path TO "$user", public; + +INSERT INTO schema_migrations (version) VALUES ('1'); + +INSERT INTO schema_migrations (version) VALUES ('2'); + +INSERT INTO schema_migrations (version) VALUES ('20121019101022'); + +INSERT INTO schema_migrations (version) VALUES ('20121104004639'); + +INSERT INTO schema_migrations (version) VALUES ('20121104085711'); + +INSERT INTO schema_migrations (version) VALUES ('20121121233818'); + +INSERT INTO schema_migrations (version) VALUES ('20130214175758'); + +INSERT INTO schema_migrations (version) VALUES ('20130214181128'); + +INSERT INTO schema_migrations (version) VALUES ('20130222185624'); + +INSERT INTO schema_migrations (version) VALUES ('20130425165150'); + +INSERT INTO schema_migrations (version) VALUES ('20130508085004'); + +INSERT INTO schema_migrations (version) VALUES ('20130513092219'); + +INSERT INTO schema_migrations (version) VALUES ('20130514094755'); + +INSERT INTO schema_migrations (version) VALUES ('20130618210236'); + +INSERT INTO schema_migrations (version) VALUES ('20130621102219'); + +INSERT INTO schema_migrations (version) VALUES ('20130621103053'); + +INSERT INTO schema_migrations (version) VALUES ('20130621103501'); + +INSERT INTO schema_migrations (version) VALUES ('20130621105452'); + +INSERT INTO schema_migrations (version) VALUES ('20130703233851'); + +INSERT INTO schema_migrations (version) VALUES ('20130703234011'); + +INSERT INTO schema_migrations (version) VALUES ('20130703234042'); + +INSERT INTO schema_migrations (version) VALUES ('20130723160206'); + +INSERT INTO schema_migrations (version) VALUES ('20131017144321'); + +INSERT INTO schema_migrations (version) VALUES ('20131025202608'); + +INSERT INTO schema_migrations (version) VALUES ('20131027215517'); + +INSERT INTO schema_migrations (version) VALUES ('20131029202724'); + +INSERT INTO schema_migrations (version) VALUES ('20131103221044'); + +INSERT INTO schema_migrations (version) VALUES ('20131104004235'); + +INSERT INTO schema_migrations (version) VALUES ('20131104013634'); + +INSERT INTO schema_migrations (version) VALUES ('20131104013829'); + +INSERT INTO schema_migrations (version) VALUES ('20131104032622'); + +INSERT INTO schema_migrations (version) VALUES ('20131220160257'); + +INSERT INTO schema_migrations (version) VALUES ('20131227110122'); + +INSERT INTO schema_migrations (version) VALUES ('20131227142805'); + +INSERT INTO schema_migrations (version) VALUES ('20131227155440'); + +INSERT INTO schema_migrations (version) VALUES ('20131231110424'); + +INSERT INTO schema_migrations (version) VALUES ('20140119161433'); + +INSERT INTO schema_migrations (version) VALUES ('20140513141718'); + +INSERT INTO schema_migrations (version) VALUES ('20140514225527'); + +INSERT INTO schema_migrations (version) VALUES ('20150329193421'); + +INSERT INTO schema_migrations (version) VALUES ('20150330200315'); + +INSERT INTO schema_migrations (version) VALUES ('20150422162806'); + +INSERT INTO schema_migrations (version) VALUES ('20180221161343'); + +INSERT INTO schema_migrations (version) VALUES ('20180501093846'); + +INSERT INTO schema_migrations (version) VALUES ('20180514193153'); + +INSERT INTO schema_migrations (version) VALUES ('20180524143938'); + +INSERT INTO schema_migrations (version) VALUES ('20180525141138'); + +INSERT INTO schema_migrations (version) VALUES ('20180529144243'); + +INSERT INTO schema_migrations (version) VALUES ('20180530180546'); + +INSERT INTO schema_migrations (version) VALUES ('20180604145622'); + +INSERT INTO schema_migrations (version) VALUES ('20180828160700'); + +INSERT INTO schema_migrations (version) VALUES ('20180831161349'); + +INSERT INTO schema_migrations (version) VALUES ('20180924164456'); + +INSERT INTO schema_migrations (version) VALUES ('20181004200104'); + +INSERT INTO schema_migrations (version) VALUES ('20190319121401'); + +INSERT INTO schema_migrations (version) VALUES ('20190322180602'); + +INSERT INTO schema_migrations (version) VALUES ('20190411192828'); + +INSERT INTO schema_migrations (version) VALUES ('20190412163011'); + +INSERT INTO schema_migrations (version) VALUES ('20190523213421'); + +INSERT INTO schema_migrations (version) VALUES ('20190523225323'); + From 5d0ec9ee9e03c6b732cbc3d6a58d20d7653ba31b Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Fri, 24 May 2019 19:01:49 +0200 Subject: [PATCH 08/33] Specs++ --- spec/controllers/offers_controller_spec.rb | 89 +++++++++++++++++++--- 1 file changed, 80 insertions(+), 9 deletions(-) diff --git a/spec/controllers/offers_controller_spec.rb b/spec/controllers/offers_controller_spec.rb index cca4c262c..9eccf526d 100644 --- a/spec/controllers/offers_controller_spec.rb +++ b/spec/controllers/offers_controller_spec.rb @@ -12,6 +12,12 @@ organization: organization, category: test_category) end + let!(:other_offer) do + Fabricate(:offer, + user: another_member.user, + organization: organization, + category: test_category) + end include_context "stub browser locale" @@ -22,14 +28,47 @@ it "populates an array of offers" do login(another_member.user) - get "index" - expect(assigns(:offers)).to eq([offer]) + get :index + + expect(assigns(:offers)).to eq([other_offer, offer]) + end + + context "when one offer is not active" do + before do + other_offer.active = false + other_offer.save! + end + + it "only returns active offers" do + login(another_member.user) + + get :index + + expect(assigns(:offers)).to eq([offer]) + end + end + + context "when one offer's user is not active" do + before do + member.active = false + member.save! + end + + it "only returns offers from active users" do + login(another_member.user) + + get :index + + expect(assigns(:offers)).to eq([other_offer]) + end end end context "with another organization" do it "skips the original org's offers" do login(yet_another_member.user) - get "index" + + get :index + expect(assigns(:offers)).to eq([]) end end @@ -37,19 +76,51 @@ describe "GET #index (search)" do before { login(another_member.user) } + before do + offer.title = "Queridos compañeros" + offer.save! + end it "populates an array of offers" do - get "index", q: offer.title.split(/\s/).first + get :index, q: 'compañeros' - expect(assigns(:offers).size).to eq 1 - expect(assigns(:offers)[0]).to eq offer - expect(assigns(:offers).to_a).to eq([offer]) + expect(assigns(:offers)).to eq([offer]) end it "allows to search by partial word" do - get :index, q: offer.title.split(/\s/).first[0..-2] + get :index, q: 'compañ' + + expect(assigns(:offers)).to eq([offer]) + end + + context "when one offer is not active" do + before do + other_offer.active = false + other_offer.save! + end + + it "only returns active offers" do + login(another_member.user) + + get :index - expect(assigns(:offers)).to include offer + expect(assigns(:offers)).to eq([offer]) + end + end + + context "when one offer's user is not active" do + before do + member.active = false + member.save! + end + + it "only returns offers from active users" do + login(another_member.user) + + get :index + + expect(assigns(:offers)).to eq([other_offer]) + end end end From 30adf3d0892e305ba5f2db69692cb69d95d8abfe Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Sat, 25 May 2019 02:01:28 +0200 Subject: [PATCH 09/33] Install correct Bundler version on Travis CI --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 95c06230b..cdb98cbec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,8 @@ env: global: - DATABASE_URL=postgres://postgres@localhost/timeoverflow_test - CC_TEST_REPORTER_ID=025bc15a0fa9afa52d86ee24fea845cf1d363f48a466bcf2cef8ab80c29acb28 +before_install: + - gem install bundler:1.17.0 before_script: - bundle exec rake db:setup - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter From 209a0e6604746ccadb0d8444d823eca21c8c3e0d Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Tue, 20 Aug 2019 21:53:06 +0200 Subject: [PATCH 10/33] fix features specs + upgrade some "group :test" gems --- Gemfile | 8 ++++---- Gemfile.lock | 33 +++++++++++++++------------------ spec/features/sign_in_spec.rb | 3 ++- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/Gemfile b/Gemfile index 09cc1803f..0daecce68 100644 --- a/Gemfile +++ b/Gemfile @@ -60,8 +60,8 @@ group :test do gem 'shoulda-matchers', '~> 3.1.2' gem 'fabrication' gem 'faker', '~> 1.9' - gem 'capybara', '~> 3.13' - gem 'selenium-webdriver', '~> 3.141' - gem 'webdrivers', '~> 3.0' - gem 'simplecov', '~> 0.16.1', require: false + gem 'capybara', '~> 3.15' + gem 'selenium-webdriver', '~> 3.142' + gem 'webdrivers', '~> 4.1.2' + gem 'simplecov', '~> 0.17', require: false end diff --git a/Gemfile.lock b/Gemfile.lock index 173fbbb20..1ce576e7f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -84,7 +84,7 @@ GEM capistrano-rbenv (2.1.3) capistrano (~> 3.1) sshkit (~> 1.3) - capybara (3.13.2) + capybara (3.15.1) addressable mini_mime (>= 0.1.3) nokogiri (~> 1.8) @@ -92,8 +92,8 @@ GEM rack-test (>= 0.6.3) regexp_parser (~> 1.2) xpath (~> 3.2) - childprocess (0.9.0) - ffi (~> 1.0, >= 1.0.11) + childprocess (1.0.1) + rake (< 13.0) chronic (0.10.2) coderay (1.1.2) coffee-rails (4.1.0) @@ -117,7 +117,7 @@ GEM responders warden (~> 1.2.3) diff-lcs (1.3) - docile (1.3.1) + docile (1.3.2) domain_name (0.5.20170223) unf (>= 0.0.5, < 1.0.0) dotenv (2.7.1) @@ -132,7 +132,6 @@ GEM fabrication (2.11.3) faker (1.9.3) i18n (>= 0.7) - ffi (1.10.0) formtastic (3.1.5) actionpack (>= 3.2.13) formtastic_i18n (0.6.0) @@ -196,7 +195,6 @@ GEM net-scp (1.2.1) net-ssh (>= 2.6.5) net-ssh (2.9.2) - net_http_ssl_fix (0.0.10) netrc (0.11.0) nokogiri (1.8.5) mini_portile2 (~> 2.3.0) @@ -263,7 +261,7 @@ GEM polyamorous (~> 1.3.2) rdiscount (2.1.7.1) redis (4.0.1) - regexp_parser (1.3.0) + regexp_parser (1.6.0) responders (2.4.0) actionpack (>= 4.2.0, < 5.3) railties (>= 4.2.0, < 5.3) @@ -298,7 +296,7 @@ GEM ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) ruby-progressbar (1.9.0) - rubyzip (1.2.2) + rubyzip (1.2.3) rufus-scheduler (3.4.2) et-orbi (~> 1.0) sass (3.4.21) @@ -310,8 +308,8 @@ GEM tilt (>= 1.1, < 3) select2-rails (4.0.1) thor (~> 0.14) - selenium-webdriver (3.141.0) - childprocess (~> 0.5) + selenium-webdriver (3.142.3) + childprocess (>= 0.5, < 2.0) rubyzip (~> 1.2, >= 1.2.2) shoulda-matchers (3.1.2) activesupport (>= 4.0.0) @@ -326,7 +324,7 @@ GEM simple_form (3.1.0) actionpack (~> 4.0) activemodel (~> 4.0) - simplecov (0.16.1) + simplecov (0.17.0) docile (~> 1.1) json (>= 1.8, < 3) simplecov-html (~> 0.10.0) @@ -369,11 +367,10 @@ GEM binding_of_caller (>= 0.7.2) railties (>= 4.0) sprockets-rails (>= 2.0, < 4.0) - webdrivers (3.7.2) - net_http_ssl_fix + webdrivers (4.1.2) nokogiri (~> 1.6) rubyzip (~> 1.0) - selenium-webdriver (~> 3.0) + selenium-webdriver (>= 3.0, < 4.0) whenever (0.9.4) chronic (>= 0.6.3) xpath (3.2.0) @@ -392,7 +389,7 @@ DEPENDENCIES capistrano (~> 3.1) capistrano-rails (~> 1.1) capistrano-rbenv (~> 2.1) - capybara (~> 3.13) + capybara (~> 3.15) coffee-rails dalli database_cleaner (= 1.6.2) @@ -421,17 +418,17 @@ DEPENDENCIES rufus-scheduler (~> 3.4.2) sass-rails (~> 5.0.7) select2-rails - selenium-webdriver (~> 3.141) + selenium-webdriver (~> 3.142) shoulda-matchers (~> 3.1.2) sidekiq (= 5.1.3) sidekiq-cron (= 0.6.3) simple_form (>= 3.0.0) - simplecov (~> 0.16.1) + simplecov (~> 0.17) skylight uglifier (= 2.7.2) unicorn web-console (= 2.1.3) - webdrivers (~> 3.0) + webdrivers (~> 4.1.2) whenever RUBY VERSION diff --git a/spec/features/sign_in_spec.rb b/spec/features/sign_in_spec.rb index bad23fd2a..03b83d9d9 100644 --- a/spec/features/sign_in_spec.rb +++ b/spec/features/sign_in_spec.rb @@ -7,7 +7,7 @@ context 'with a valid password' do it 'signs the user in' do - expect(Capybara.current_session.driver.browser.manage.cookie_named('_timeoverflow_session')).to be_falsy + Capybara.current_session.driver.browser.manage.delete_cookie('_timeoverflow_session') sign_in_with(user.email, user.password) @@ -19,6 +19,7 @@ context 'with an invalid password' do it 'shows an error' do sign_in_with(user.email, 'wrong_password') + expect(page).to have_content(I18n.t('devise.failure.invalid')) end end From 0a8d950920cab4805e29914dfe64b8f94ff7cf01 Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Tue, 20 Aug 2019 22:09:05 +0200 Subject: [PATCH 11/33] Travis: use Trusty for now, Xenial dist comes with postgresql 10 (and we are not ready yet) --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index cdb98cbec..2b0ff1d7d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: ruby +dist: trusty cache: bundler bundler_args: '--without development' env: From 1d2e25e3a71a69a88971d49b90e53e2ac73e38dc Mon Sep 17 00:00:00 2001 From: sseerrggii Date: Thu, 19 Sep 2019 13:05:44 +0200 Subject: [PATCH 12/33] New translations --- config/locales/ca.yml | 6 ++-- config/locales/es.yml | 4 +-- config/locales/eu.yml | 82 ++++++++++++++++++++++--------------------- 3 files changed, 48 insertions(+), 44 deletions(-) diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 70a0c7ff9..f94ae85ff 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -347,8 +347,10 @@ ca: mailers_globals: footer: text: "%{organization_name} en" - text_donation: L'associació ADBdT ofereix TimeOverflow de forma gratuïta als Bancs de Temps. Amb una donació de %{href} pots ajudar a mantenir i millorar la plataforma. - text_donation_link: 1€ al mes + text_donation: L'associació ADBdT ofereix TimeOverflow de forma gratuïta als Bancs de Temps. Si vols contribuir a mantenir i millorar la plataforma, %{href}. + text_donation_link: 'visita aquesta pàgina + +' multi_transfers: multi_transfers: 'Transferències múltiples ' step: diff --git a/config/locales/es.yml b/config/locales/es.yml index 5b9aee99c..2706aa7b1 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -347,8 +347,8 @@ es: mailers_globals: footer: text: "%{organization_name} en" - text_donation: La asociación ADBdT ofrece TimeOverflow de forma gratuita a los Bancos de Tiempo. Con una donación de %{href} puedes ayudar a mantener y mejorar la plataforma. - text_donation_link: 1€ al mes + text_donation: La asociación ADBdT ofrece TimeOverflow de forma gratuita a los Bancos de Tiempo. Si quieres contribuir a mantener y mejorar la plataforma, %{href}. + text_donation_link: visita esta página multi_transfers: multi_transfers: Transferencias múltiples step: diff --git a/config/locales/eu.yml b/config/locales/eu.yml index 950df53d9..e852e5089 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -22,9 +22,9 @@ eu: created_at: Sortua updated_at: Eguneratua inquiry: - is_group: + is_group: Taldeko eskaera offer: - is_group: + is_group: Taldeko eskaintza organization: address: Helbidea city: Herria @@ -73,7 +73,7 @@ eu: notifications: Jasotako jakinarazpenak organization: Antolaketa phone: Telefono zenbakia - push_notifications: + push_notifications: Mugikorrean mezuak jaso registration_date: Erregistratze eguna registration_number: Erabiltzaile kodea superadmin: Sistemaren administratzailea @@ -97,7 +97,7 @@ eu: models: category: one: Gaia - other: '' + other: gaiak comment: one: Azalpena other: Azalpenak @@ -235,10 +235,10 @@ eu: edit_user: Erabiltzailea editatu help_current_password: Zure pasahitza behar dugu aldaketak baieztatzeko help_password: Aldatu nahi ez baduzu, utzi zurian. - password: - password_confirmation: - unhappy: - update: + password: Pasahitza + password_confirmation: Pasahitza baieztatu + unhappy: Triste + update: Eguneratu new: password: Pasahitza password_confirmation: Pasahitza baieztatu. @@ -275,8 +275,10 @@ eu: unlocked: Zure kontua desblokeatua izan da. Sartu jarraitzeko. errors: internal_server_error: - description: - title: + description: |- + Kontsulta honetan oker bat dagoela dirudi. Mezu bat bidali dugu , teknikarien sailera eta ahal bezain laxter konpontzen saiatuko gara. + Sentitzen dugu. + title: Zerbitzariaren barne akatsa. messages: already_confirmed: Baieztatu izan da , Saiatu sartzen. confirmation_period_expired: "%{period}an baieztatzea beharrezkoa da. Eskatu berria." @@ -287,8 +289,8 @@ eu: one: Arazo batek ez du uzten %{resource} gorde dadin. other: "%{count} arazok ez dute uzten %{resource} gorde dadin" not_found: - description: - title: + description: Bila zabiltzan orrialdea ez da exititzen. Helbidea oker idatzia egon daiteke edo orrialdea lekuz aldatua izan da. + title: Ez da topatu global: add_new: Berria sortu all: Dena. @@ -298,21 +300,21 @@ eu: balance: Balantzea cancel_membership: Betirako borratu contact_details: Kontaktuaren datuak - create: + create: Sortu date: Eguna. delete: Ezabatu demote: Ohiko erabiltzaile biurtu edit: Aldaketak egin filter: Iragazkia - from: + from: tik give_time: Denbora eman - home: + home: Etxea information: Informazioa locales_header: Hizkuntza aldatu member_count: Erabiltzaile zenbakia more: 'Gehiago ikusi ' movements: Mugimenduak - next: + next: Hurrengoa promote: Administratzaile bihurtu reason: Arrazoia required_field: Derrigorrez bete beharrekoa @@ -323,7 +325,7 @@ eu: statistics: Estatistika table: actions: Ekintzak - to: + to: ra inquiries: edit: submit: Eskaera aldatu @@ -341,39 +343,39 @@ eu: report: report_title: TXOSTENA locales: - ar: + ar: Arabiera ca: Katalanera - en: Inglesa + en: Ingelesa es: Espainiera - eu: - fr: - gl: - pt: - pt-BR: Portugesa + eu: Euskara + fr: Fantsesa + gl: Galiziera + pt: Portugalera + pt-BR: Portugaldarra mailers_globals: footer: text: "%{organization_name}" text_donation: ADBdt elkarteak TimeOverflow zerbitzua , dohainik eskaintzen die denbora bankuei. Plataforma mantendu eta hobetzeko lagun dezakete %{href} ko emari batekin. text_donation_link: hilean €1ekin multi_transfers: - multi_transfers: + multi_transfers: Transferentzia ugariak step: confirm: - description: - type_of_transfer: + description: Aldaketak baieztatu + type_of_transfer: Transferentzia motak select_type: - description: + description: Transferentzia mota hautatu set_params: - description: + description: Transferitzera zoazen kantitatea zehaztu, iradokizunak , eskaintzak ( baldin badaude) set_source: - description: + description: Denbora transferituko duzun kontua, aukeratu. set_target: - description: - success: + description: Denbora jasoko duten kontuak aukera itzazu. + success: Arrakastatsu eginiko transferentziak types: - many_to_one: - one_to_many: - one_to_one: + many_to_one: Ugaritik bakarrera + one_to_many: Bakarretik ugarira + one_to_one: Banaka offers: edit: submit: Eskaintza aldatu @@ -404,12 +406,12 @@ eu: contact_information: kontaktuaren informazioa pages: about: - app-mobile: - app-mobile-text: + app-mobile: Mugikorrerako Appa + app-mobile-text: TimeOverflow mugikorrean erabiltzeko Appa prest da
App hau Bartzelonako udaletxearen laguntzari esker sortu da . %{impulsem_link} (Barcelona Activa) 2017-2018 programaren bitartez. banner-button: Sartzea eskatzen du banner-subtitle: Martxan jartzen edo erakustaldi bat eginez lagunduko dizugu banner-title: Denbora banku bat al zara? - donate-link: + donate-link: Eman ezazu hilean €1 donate-text: komunitate askori babesteko asmotan ADBdt elkarteak , TimeOverflow plataforma eskaintzen die Denbora Banku guztiei. Hausnar ezazu %{donate_link} mantenu eta berritze lanetan laguntzeko. donate-title: Laguntzan parte hartu empower-adbdt: ADBdt @@ -432,7 +434,7 @@ eu: feature-text-4: Denbora bankuko partaideek, sistemaren bidez, beste partaideekin kontatua egin dezakete feature-text-5: Eskaintza eta eskariak argitaratu feature-text-6: Beste erabiltzaileei orduak ordaindu - impulsem-link: + impulsem-link: Impulsem el que fas subtitle: TimeOverflow librea dohakoa eta kolaborazio bidezkoa da title: Denbora bankuek diseinaturiko softwarea, title2: Denbora bankuentzat @@ -547,7 +549,7 @@ eu: create: Erabiltzaile berria sortu manage_warning: manage_warning_angular: " {{username}} erabiltzailearen onurak, aldatuko diztuzu" - members: + members: Kideak user_created: "%{uid} %{name} erabiltzailea gorde da" member_card: active_ago: From a2e0e10eed40a5f75a03125bc82a55190c8adcfc Mon Sep 17 00:00:00 2001 From: sseerrggii Date: Thu, 19 Sep 2019 13:12:49 +0200 Subject: [PATCH 13/33] =?UTF-8?q?canvis=20traducci=C3=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/locales/ca.yml | 4 +--- config/locales/es.yml | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/config/locales/ca.yml b/config/locales/ca.yml index f94ae85ff..23159639d 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -348,9 +348,7 @@ ca: footer: text: "%{organization_name} en" text_donation: L'associació ADBdT ofereix TimeOverflow de forma gratuïta als Bancs de Temps. Si vols contribuir a mantenir i millorar la plataforma, %{href}. - text_donation_link: 'visita aquesta pàgina - -' + text_donation_link: visita aquesta web multi_transfers: multi_transfers: 'Transferències múltiples ' step: diff --git a/config/locales/es.yml b/config/locales/es.yml index 2706aa7b1..08f25c588 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -348,7 +348,7 @@ es: footer: text: "%{organization_name} en" text_donation: La asociación ADBdT ofrece TimeOverflow de forma gratuita a los Bancos de Tiempo. Si quieres contribuir a mantener y mejorar la plataforma, %{href}. - text_donation_link: visita esta página + text_donation_link: visita esta web multi_transfers: multi_transfers: Transferencias múltiples step: From 096fcce484ffd4f843955bcc2cd36627e26e43bc Mon Sep 17 00:00:00 2001 From: enricostano Date: Fri, 20 Sep 2019 11:22:44 +0200 Subject: [PATCH 14/33] Revert "Merge pull request #465 from coopdevs/feature/switch-from-elastic-to-pg-search-la-buena" This reverts commit 9f7b99a794f2934d67b2b0f3c91533060eccd973, reversing changes made to ad9a8f0960a80ce30e8d031c511180cc5888f37f. --- .travis.yml | 4 + Gemfile | 3 +- Gemfile.lock | 23 +- app/controllers/members_controller.rb | 5 + app/controllers/posts_controller.rb | 39 +- app/models/member.rb | 12 + app/models/post.rb | 70 +- config/application.rb | 4 - config/initializers/elasticsearch.rb | 3 + ...90523213421_add_tsvector_column_to_post.rb | 32 - ...0190523225323_enable_unaccent_extension.rb | 9 - db/schema.rb | 223 ++++ db/structure.sql | 1141 ----------------- lib/tasks/elasticsearch.rake | 1 + spec/controllers/offers_controller_spec.rb | 99 +- 15 files changed, 368 insertions(+), 1300 deletions(-) create mode 100644 config/initializers/elasticsearch.rb delete mode 100644 db/migrate/20190523213421_add_tsvector_column_to_post.rb delete mode 100644 db/migrate/20190523225323_enable_unaccent_extension.rb create mode 100644 db/schema.rb delete mode 100644 db/structure.sql create mode 100644 lib/tasks/elasticsearch.rake diff --git a/.travis.yml b/.travis.yml index 2b0ff1d7d..0b4232a41 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,11 @@ before_script: - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter - chmod +x ./cc-test-reporter - ./cc-test-reporter before-build + # allow elasticsearch to be ready - https://docs.travis-ci.com/user/database-setup/#ElasticSearch + - sleep 10 after_script: - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT +services: + - elasticsearch addons: chrome: stable diff --git a/Gemfile b/Gemfile index 0daecce68..811334e20 100644 --- a/Gemfile +++ b/Gemfile @@ -18,9 +18,10 @@ gem 'kaminari', '~> 1.1.1' gem "simple_form", ">= 3.0.0" gem 'rollbar', '2.8.3' gem 'whenever', require: false -gem 'pg_search', '2.1.4' gem 'prawn', '~> 2.2.0' gem 'prawn-table', '~> 0.2.2' +gem 'elasticsearch-model' +gem 'elasticsearch-rails' gem 'skylight' gem 'sidekiq', '5.1.3' gem 'sidekiq-cron', '0.6.3' diff --git a/Gemfile.lock b/Gemfile.lock index 1ce576e7f..00e7aed0f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -124,6 +124,19 @@ GEM dotenv-rails (2.7.1) dotenv (= 2.7.1) railties (>= 3.2, < 6.1) + elasticsearch (1.0.8) + elasticsearch-api (= 1.0.7) + elasticsearch-transport (= 1.0.7) + elasticsearch-api (1.0.7) + multi_json + elasticsearch-model (0.1.7) + activesupport (> 3) + elasticsearch (> 0.4) + hashie + elasticsearch-rails (0.1.7) + elasticsearch-transport (1.0.7) + faraday + multi_json erubi (1.7.1) erubis (2.7.0) et-orbi (1.1.2) @@ -141,6 +154,7 @@ GEM has_scope (0.6.0) actionpack (>= 3.2, < 5) activesupport (>= 3.2, < 5) + hashie (3.4.1) hstore_translate (1.0.0) activerecord (>= 3.1.0) http-cookie (1.0.3) @@ -192,6 +206,7 @@ GEM mini_portile2 (2.3.0) minitest (5.11.3) multi_json (1.11.2) + multipart-post (2.0.0) net-scp (1.2.1) net-ssh (>= 2.6.5) net-ssh (2.9.2) @@ -204,9 +219,6 @@ GEM ast (~> 2.4.0) pdf-core (0.7.0) pg (0.17.1) - pg_search (2.1.4) - activerecord (>= 4.2) - activesupport (>= 4.2) polyamorous (1.3.3) activerecord (>= 3.0) powerpack (0.1.1) @@ -395,6 +407,8 @@ DEPENDENCIES database_cleaner (= 1.6.2) devise (~> 4.5.0) dotenv-rails (~> 2.7.1) + elasticsearch-model + elasticsearch-rails fabrication faker (~> 1.9) has_scope @@ -405,7 +419,6 @@ DEPENDENCIES letter_opener (= 1.4.1) localeapp (= 2.1.1) pg (= 0.17.1) - pg_search (= 2.1.4) prawn (~> 2.2.0) prawn-table (~> 0.2.2) pundit (~> 2.0.0) @@ -435,4 +448,4 @@ RUBY VERSION ruby 2.3.0p0 BUNDLED WITH - 1.17.0 + 1.16.2 diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index d8dff153d..5545f4186 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -20,6 +20,11 @@ def toggle_manager def toggle_active find_member @member.toggle(:active).save! + if @member.active + @member.add_all_posts_to_index + else + @member.remove_all_posts_from_index + end respond_to do |format| format.json { head :ok } format.html { redirect_to :back } diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 55fe2d32e..a74db794b 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -4,22 +4,31 @@ class PostsController < ApplicationController has_scope :by_organization, as: :org def index - context = model.active.of_active_members - if current_organization.present? - context = context.where( - organization_id: current_organization.id - ) + if (query = params[:q]).present? + # match query term on fields + must = [ { multi_match: { + query: query.to_s, + type: "phrase_prefix", + fields: ["title^2", "description", "tags^2"] + } } ] + if current_organization.present? + # filter by organization + must << { term: { organization_id: { value: current_organization.id } } } + end + posts = model.__elasticsearch__.search( + query: { + bool: { + must: must + } + } + ).page(params[:page]).per(25).records + else + posts = model.active.of_active_members + if current_organization.present? + posts = posts.merge(current_organization.posts) + end + posts = apply_scopes(posts).page(params[:page]).per(25) end - - posts = if (query = params[:q]).present? - context. - search_by_query(query). - page(params[:page]). - per(25) - else - apply_scopes(context).page(params[:page]).per(25) - end - instance_variable_set("@#{resources}", posts) end diff --git a/app/models/member.rb b/app/models/member.rb index 47739daa0..6e5381860 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -44,6 +44,18 @@ def display_id member_uid end + def remove_all_posts_from_index + Post.with_member.where("members.id = ?", self.id).find_each do |post| + post.delete_document + end + end + + def add_all_posts_to_index + Post.with_member.where("members.id = ?", self.id).find_each do |post| + post.update_or_delete_document(self) + end + end + def assign_registration_number self.member_uid ||= organization.next_reg_number_seq end diff --git a/app/models/post.rb b/app/models/post.rb index 54711fef9..485f0f319 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -1,16 +1,40 @@ +require 'elasticsearch/model' + class Post < ActiveRecord::Base include Taggable - include PgSearch - - pg_search_scope :search_by_query, - against: [:title, :description, :tags], - ignoring: :accents, - using: { - tsearch: { - prefix: true, - tsvector_column: 'tsv' - } - } + + # Elasticsearch::Model doesn't work well with STI, so + # include it in subclasses directly. + def self.inherited(child) + super + + child.instance_eval do + include Elasticsearch::Model + + after_commit :index_document, on: :create + after_commit :update_or_delete_document, on: :update + after_commit :delete_document, on: :destroy + + settings( + analysis: { + analyzer: { + normal: { + tokenizer: "standard", + # lowercase, unaccent + filter: %w[lowercase asciifolding] + } + } + } + ) do + mapping do + indexes :title, analyzer: "normal" + indexes :description, analyzer: "normal" + indexes :tags + indexes :organization_id, type: :integer + end + end + end + end attr_reader :member_id @@ -48,6 +72,30 @@ class Post < ActiveRecord::Base validates :category, presence: true validates :title, presence: true + def index_document + __elasticsearch__.index_document + end + + # pass member when doing bulk things + def update_or_delete_document(member = nil) + member ||= self.member + if active && member.try(:active) + begin + __elasticsearch__.update_document + rescue # document was not in the index. TODO: more specifi exception class + __elasticsearch__.index_document + end + else + __elasticsearch__.delete_document + end + rescue # document was not in the index. TODO: more specifi exception class + end + + def delete_document + __elasticsearch__.delete_document + rescue # document was not in the index. TODO: more specifi exception class + end + def as_indexed_json(*) as_json(only: [:title, :description, :tags, :organization_id]) end diff --git a/config/application.rb b/config/application.rb index 4edfc6c1d..4bba4fc1b 100644 --- a/config/application.rb +++ b/config/application.rb @@ -35,9 +35,5 @@ class Application < Rails::Application # ActiveJob configuration config.active_job.queue_adapter = :sidekiq - - # Use db/structure.sql with SQL as schema format - # This is needed to store in the schema SQL statements not covered by the ORM - config.active_record.schema_format = :sql end end diff --git a/config/initializers/elasticsearch.rb b/config/initializers/elasticsearch.rb new file mode 100644 index 000000000..4f8d88b9e --- /dev/null +++ b/config/initializers/elasticsearch.rb @@ -0,0 +1,3 @@ +if ENV["ELASTICSEARCH_URL"].present? + Elasticsearch::Model.client = Elasticsearch::Client.new host: ENV["ELASTICSEARCH_URL"] +end diff --git a/db/migrate/20190523213421_add_tsvector_column_to_post.rb b/db/migrate/20190523213421_add_tsvector_column_to_post.rb deleted file mode 100644 index fe124d235..000000000 --- a/db/migrate/20190523213421_add_tsvector_column_to_post.rb +++ /dev/null @@ -1,32 +0,0 @@ -class AddTsvectorColumnToPost < ActiveRecord::Migration - def up - execute <<-SQL - ALTER TABLE posts ADD COLUMN tsv tsvector; - - CREATE FUNCTION posts_trigger() RETURNS trigger AS $$ - begin - new.tsv := - to_tsvector('simple', unaccent(coalesce(new.title::text, ''))) || - to_tsvector('simple', unaccent(coalesce(new.description::text, ''))) || - to_tsvector('simple', unaccent(coalesce(new.tags::text, ''))); - return new; - end - $$ LANGUAGE plpgsql; - - CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE - ON posts FOR EACH ROW EXECUTE PROCEDURE posts_trigger(); - SQL - - add_index :posts, :tsv, using: "gin" - end - - def down - execute <<-SQL - DROP TRIGGER tsvectorupdate ON posts; - DROP FUNCTION posts_trigger(); - SQL - - remove_index :posts, :tsv - remove_column :posts, :tsv - end -end diff --git a/db/migrate/20190523225323_enable_unaccent_extension.rb b/db/migrate/20190523225323_enable_unaccent_extension.rb deleted file mode 100644 index d5dcc420f..000000000 --- a/db/migrate/20190523225323_enable_unaccent_extension.rb +++ /dev/null @@ -1,9 +0,0 @@ -class EnableUnaccentExtension < ActiveRecord::Migration - def up - enable_extension "unaccent" - end - - def down - disable_extension "unaccent" - end -end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 000000000..bfcd9e381 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,223 @@ +# encoding: UTF-8 +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 20190412163011) do + + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + enable_extension "hstore" + enable_extension "pg_trgm" + + create_table "accounts", force: :cascade do |t| + t.integer "accountable_id" + t.string "accountable_type" + t.integer "balance", default: 0 + t.integer "max_allowed_balance" + t.integer "min_allowed_balance" + t.boolean "flagged" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "organization_id" + end + + add_index "accounts", ["accountable_type", "accountable_id"], name: "index_accounts_on_accountable_type_and_accountable_id", using: :btree + add_index "accounts", ["organization_id"], name: "index_accounts_on_organization_id", using: :btree + + create_table "active_admin_comments", force: :cascade do |t| + t.string "namespace" + t.text "body" + t.string "resource_id", null: false + t.string "resource_type", null: false + t.integer "author_id" + t.string "author_type" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "active_admin_comments", ["author_type", "author_id"], name: "index_active_admin_comments_on_author_type_and_author_id", using: :btree + add_index "active_admin_comments", ["namespace"], name: "index_active_admin_comments_on_namespace", using: :btree + add_index "active_admin_comments", ["resource_type", "resource_id"], name: "index_active_admin_comments_on_resource_type_and_resource_id", using: :btree + + create_table "categories", force: :cascade do |t| + t.datetime "created_at" + t.datetime "updated_at" + t.hstore "name_translations" + end + + create_table "device_tokens", force: :cascade do |t| + t.integer "user_id", null: false + t.string "token", null: false + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "device_tokens", ["user_id", "token"], name: "index_device_tokens_on_user_id_and_token", unique: true, using: :btree + + create_table "documents", force: :cascade do |t| + t.integer "documentable_id" + t.string "documentable_type" + t.text "title" + t.text "content" + t.string "label" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "documents", ["documentable_id", "documentable_type"], name: "index_documents_on_documentable_id_and_documentable_type", using: :btree + add_index "documents", ["label"], name: "index_documents_on_label", using: :btree + + create_table "events", force: :cascade do |t| + t.integer "action", null: false + t.integer "post_id" + t.integer "member_id" + t.integer "transfer_id" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "events", ["member_id"], name: "index_events_on_member_id", where: "(member_id IS NOT NULL)", using: :btree + add_index "events", ["post_id"], name: "index_events_on_post_id", where: "(post_id IS NOT NULL)", using: :btree + add_index "events", ["transfer_id"], name: "index_events_on_transfer_id", where: "(transfer_id IS NOT NULL)", using: :btree + + create_table "members", force: :cascade do |t| + t.integer "user_id" + t.integer "organization_id" + t.boolean "manager" + t.datetime "created_at" + t.datetime "updated_at" + t.date "entry_date" + t.integer "member_uid" + t.boolean "active", default: true + end + + add_index "members", ["organization_id"], name: "index_members_on_organization_id", using: :btree + add_index "members", ["user_id"], name: "index_members_on_user_id", using: :btree + + create_table "movements", force: :cascade do |t| + t.integer "account_id" + t.integer "transfer_id" + t.integer "amount" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "movements", ["account_id"], name: "index_movements_on_account_id", using: :btree + add_index "movements", ["transfer_id"], name: "index_movements_on_transfer_id", using: :btree + + create_table "organizations", force: :cascade do |t| + t.string "name", limit: 255, null: false + t.datetime "created_at" + t.datetime "updated_at" + t.integer "reg_number_seq" + t.string "theme" + t.string "email" + t.string "phone" + t.string "web" + t.text "public_opening_times" + t.text "description" + t.text "address" + t.string "neighborhood" + t.string "city" + t.string "domain" + end + + add_index "organizations", ["name"], name: "index_organizations_on_name", unique: true, using: :btree + + create_table "posts", force: :cascade do |t| + t.string "title" + t.string "type" + t.integer "category_id" + t.integer "user_id" + t.text "description" + t.date "start_on" + t.date "end_on" + t.datetime "created_at" + t.datetime "updated_at" + t.text "tags", array: true + t.integer "organization_id" + t.boolean "active", default: true + t.boolean "is_group", default: false + end + + add_index "posts", ["category_id"], name: "index_posts_on_category_id", using: :btree + add_index "posts", ["organization_id"], name: "index_posts_on_organization_id", using: :btree + add_index "posts", ["tags"], name: "index_posts_on_tags", using: :gin + add_index "posts", ["user_id"], name: "index_posts_on_user_id", using: :btree + + create_table "push_notifications", force: :cascade do |t| + t.integer "event_id", null: false + t.integer "device_token_id", null: false + t.datetime "processed_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "title", default: "", null: false + t.string "body", default: "", null: false + t.json "data", default: {}, null: false + end + + create_table "transfers", force: :cascade do |t| + t.integer "post_id" + t.text "reason" + t.integer "operator_id" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "transfers", ["operator_id"], name: "index_transfers_on_operator_id", using: :btree + add_index "transfers", ["post_id"], name: "index_transfers_on_post_id", using: :btree + + create_table "users", force: :cascade do |t| + t.string "username", null: false + t.string "email", null: false + t.date "date_of_birth" + t.string "identity_document" + t.string "phone" + t.string "alt_phone" + t.text "address" + t.datetime "created_at" + t.datetime "updated_at" + t.datetime "deleted_at" + t.string "gender" + t.text "description" + t.boolean "active", default: true + t.datetime "terms_accepted_at" + t.string "encrypted_password", default: "", null: false + t.string "reset_password_token" + t.datetime "reset_password_sent_at" + t.datetime "remember_created_at" + t.integer "sign_in_count", default: 0 + t.datetime "current_sign_in_at" + t.datetime "last_sign_in_at" + t.string "current_sign_in_ip" + t.string "last_sign_in_ip" + t.string "confirmation_token" + t.datetime "confirmed_at" + t.datetime "confirmation_sent_at" + t.string "unconfirmed_email" + t.integer "failed_attempts", default: 0 + t.string "unlock_token" + t.datetime "locked_at" + t.string "locale", default: "es" + t.boolean "notifications", default: true + t.boolean "push_notifications", default: true, null: false + end + + add_index "users", ["email"], name: "index_users_on_email", using: :btree + + add_foreign_key "accounts", "organizations" + add_foreign_key "events", "members", name: "events_member_id_fkey" + add_foreign_key "events", "posts", name: "events_post_id_fkey" + add_foreign_key "events", "transfers", name: "events_transfer_id_fkey" + add_foreign_key "push_notifications", "device_tokens" + add_foreign_key "push_notifications", "events" +end diff --git a/db/structure.sql b/db/structure.sql deleted file mode 100644 index 5a2b8d516..000000000 --- a/db/structure.sql +++ /dev/null @@ -1,1141 +0,0 @@ --- --- PostgreSQL database dump --- - --- Dumped from database version 9.5.14 --- Dumped by pg_dump version 9.5.14 - -SET statement_timeout = 0; -SET lock_timeout = 0; -SET client_encoding = 'UTF8'; -SET standard_conforming_strings = on; -SELECT pg_catalog.set_config('search_path', '', false); -SET check_function_bodies = false; -SET client_min_messages = warning; -SET row_security = off; - --- --- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: - --- - -CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; - - --- --- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: - --- - -COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language'; - - --- --- Name: hstore; Type: EXTENSION; Schema: -; Owner: - --- - -CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public; - - --- --- Name: EXTENSION hstore; Type: COMMENT; Schema: -; Owner: - --- - -COMMENT ON EXTENSION hstore IS 'data type for storing sets of (key, value) pairs'; - - --- --- Name: pg_trgm; Type: EXTENSION; Schema: -; Owner: - --- - -CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA public; - - --- --- Name: EXTENSION pg_trgm; Type: COMMENT; Schema: -; Owner: - --- - -COMMENT ON EXTENSION pg_trgm IS 'text similarity measurement and index searching based on trigrams'; - - --- --- Name: unaccent; Type: EXTENSION; Schema: -; Owner: - --- - -CREATE EXTENSION IF NOT EXISTS unaccent WITH SCHEMA public; - - --- --- Name: EXTENSION unaccent; Type: COMMENT; Schema: -; Owner: - --- - -COMMENT ON EXTENSION unaccent IS 'text search dictionary that removes accents'; - - --- --- Name: posts_trigger(); Type: FUNCTION; Schema: public; Owner: - --- - -CREATE FUNCTION public.posts_trigger() RETURNS trigger - LANGUAGE plpgsql - AS $$ - begin - new.tsv := - to_tsvector('simple', unaccent(coalesce(new.title::text, ''))) || - to_tsvector('simple', unaccent(coalesce(new.description::text, ''))) || - to_tsvector('simple', unaccent(coalesce(new.tags::text, ''))); - return new; - end - $$; - - -SET default_tablespace = ''; - -SET default_with_oids = false; - --- --- Name: accounts; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.accounts ( - id integer NOT NULL, - accountable_id integer, - accountable_type character varying, - balance integer DEFAULT 0, - max_allowed_balance integer, - min_allowed_balance integer, - flagged boolean, - created_at timestamp without time zone, - updated_at timestamp without time zone, - organization_id integer -); - - --- --- Name: accounts_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.accounts_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: accounts_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.accounts_id_seq OWNED BY public.accounts.id; - - --- --- Name: active_admin_comments; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.active_admin_comments ( - id integer NOT NULL, - namespace character varying, - body text, - resource_id character varying NOT NULL, - resource_type character varying NOT NULL, - author_id integer, - author_type character varying, - created_at timestamp without time zone, - updated_at timestamp without time zone -); - - --- --- Name: active_admin_comments_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.active_admin_comments_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: active_admin_comments_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.active_admin_comments_id_seq OWNED BY public.active_admin_comments.id; - - --- --- Name: categories; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.categories ( - id integer NOT NULL, - created_at timestamp without time zone, - updated_at timestamp without time zone, - name_translations public.hstore -); - - --- --- Name: categories_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.categories_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: categories_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.categories_id_seq OWNED BY public.categories.id; - - --- --- Name: device_tokens; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.device_tokens ( - id integer NOT NULL, - user_id integer NOT NULL, - token character varying NOT NULL, - created_at timestamp without time zone, - updated_at timestamp without time zone -); - - --- --- Name: device_tokens_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.device_tokens_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: device_tokens_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.device_tokens_id_seq OWNED BY public.device_tokens.id; - - --- --- Name: documents; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.documents ( - id integer NOT NULL, - documentable_id integer, - documentable_type character varying, - title text, - content text, - label character varying, - created_at timestamp without time zone, - updated_at timestamp without time zone -); - - --- --- Name: documents_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.documents_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: documents_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.documents_id_seq OWNED BY public.documents.id; - - --- --- Name: events; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.events ( - id integer NOT NULL, - action integer NOT NULL, - post_id integer, - member_id integer, - transfer_id integer, - created_at timestamp without time zone, - updated_at timestamp without time zone -); - - --- --- Name: events_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.events_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: events_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.events_id_seq OWNED BY public.events.id; - - --- --- Name: members; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.members ( - id integer NOT NULL, - user_id integer, - organization_id integer, - manager boolean, - created_at timestamp without time zone, - updated_at timestamp without time zone, - entry_date date, - member_uid integer, - active boolean DEFAULT true -); - - --- --- Name: members_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.members_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: members_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.members_id_seq OWNED BY public.members.id; - - --- --- Name: movements; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.movements ( - id integer NOT NULL, - account_id integer, - transfer_id integer, - amount integer, - created_at timestamp without time zone, - updated_at timestamp without time zone -); - - --- --- Name: movements_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.movements_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: movements_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.movements_id_seq OWNED BY public.movements.id; - - --- --- Name: organizations; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.organizations ( - id integer NOT NULL, - name character varying(255) NOT NULL, - created_at timestamp without time zone, - updated_at timestamp without time zone, - reg_number_seq integer, - theme character varying, - email character varying, - phone character varying, - web character varying, - public_opening_times text, - description text, - address text, - neighborhood character varying, - city character varying, - domain character varying -); - - --- --- Name: organizations_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.organizations_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: organizations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.organizations_id_seq OWNED BY public.organizations.id; - - --- --- Name: posts; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.posts ( - id integer NOT NULL, - title character varying, - type character varying, - category_id integer, - user_id integer, - description text, - start_on date, - end_on date, - created_at timestamp without time zone, - updated_at timestamp without time zone, - tags text[], - organization_id integer, - active boolean DEFAULT true, - is_group boolean DEFAULT false, - tsv tsvector -); - - --- --- Name: posts_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.posts_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: posts_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.posts_id_seq OWNED BY public.posts.id; - - --- --- Name: push_notifications; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.push_notifications ( - id integer NOT NULL, - event_id integer NOT NULL, - device_token_id integer NOT NULL, - processed_at timestamp without time zone, - created_at timestamp without time zone NOT NULL, - updated_at timestamp without time zone NOT NULL, - title character varying DEFAULT ''::character varying NOT NULL, - body character varying DEFAULT ''::character varying NOT NULL, - data json DEFAULT '{}'::json NOT NULL -); - - --- --- Name: push_notifications_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.push_notifications_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: push_notifications_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.push_notifications_id_seq OWNED BY public.push_notifications.id; - - --- --- Name: schema_migrations; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.schema_migrations ( - version character varying NOT NULL -); - - --- --- Name: transfers; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.transfers ( - id integer NOT NULL, - post_id integer, - reason text, - operator_id integer, - created_at timestamp without time zone, - updated_at timestamp without time zone -); - - --- --- Name: transfers_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.transfers_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: transfers_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.transfers_id_seq OWNED BY public.transfers.id; - - --- --- Name: users; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.users ( - id integer NOT NULL, - username character varying NOT NULL, - email character varying NOT NULL, - date_of_birth date, - identity_document character varying, - phone character varying, - alt_phone character varying, - address text, - created_at timestamp without time zone, - updated_at timestamp without time zone, - deleted_at timestamp without time zone, - gender character varying, - description text, - active boolean DEFAULT true, - terms_accepted_at timestamp without time zone, - encrypted_password character varying DEFAULT ''::character varying NOT NULL, - reset_password_token character varying, - reset_password_sent_at timestamp without time zone, - remember_created_at timestamp without time zone, - sign_in_count integer DEFAULT 0, - current_sign_in_at timestamp without time zone, - last_sign_in_at timestamp without time zone, - current_sign_in_ip character varying, - last_sign_in_ip character varying, - confirmation_token character varying, - confirmed_at timestamp without time zone, - confirmation_sent_at timestamp without time zone, - unconfirmed_email character varying, - failed_attempts integer DEFAULT 0, - unlock_token character varying, - locked_at timestamp without time zone, - locale character varying DEFAULT 'es'::character varying, - notifications boolean DEFAULT true, - push_notifications boolean DEFAULT true NOT NULL -); - - --- --- Name: users_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.users_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: users_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.users_id_seq OWNED BY public.users.id; - - --- --- Name: id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.accounts ALTER COLUMN id SET DEFAULT nextval('public.accounts_id_seq'::regclass); - - --- --- Name: id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.active_admin_comments ALTER COLUMN id SET DEFAULT nextval('public.active_admin_comments_id_seq'::regclass); - - --- --- Name: id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.categories ALTER COLUMN id SET DEFAULT nextval('public.categories_id_seq'::regclass); - - --- --- Name: id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.device_tokens ALTER COLUMN id SET DEFAULT nextval('public.device_tokens_id_seq'::regclass); - - --- --- Name: id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.documents ALTER COLUMN id SET DEFAULT nextval('public.documents_id_seq'::regclass); - - --- --- Name: id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.events ALTER COLUMN id SET DEFAULT nextval('public.events_id_seq'::regclass); - - --- --- Name: id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.members ALTER COLUMN id SET DEFAULT nextval('public.members_id_seq'::regclass); - - --- --- Name: id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.movements ALTER COLUMN id SET DEFAULT nextval('public.movements_id_seq'::regclass); - - --- --- Name: id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.organizations ALTER COLUMN id SET DEFAULT nextval('public.organizations_id_seq'::regclass); - - --- --- Name: id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.posts ALTER COLUMN id SET DEFAULT nextval('public.posts_id_seq'::regclass); - - --- --- Name: id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.push_notifications ALTER COLUMN id SET DEFAULT nextval('public.push_notifications_id_seq'::regclass); - - --- --- Name: id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.transfers ALTER COLUMN id SET DEFAULT nextval('public.transfers_id_seq'::regclass); - - --- --- Name: id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.users ALTER COLUMN id SET DEFAULT nextval('public.users_id_seq'::regclass); - - --- --- Name: accounts_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.accounts - ADD CONSTRAINT accounts_pkey PRIMARY KEY (id); - - --- --- Name: active_admin_comments_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.active_admin_comments - ADD CONSTRAINT active_admin_comments_pkey PRIMARY KEY (id); - - --- --- Name: categories_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.categories - ADD CONSTRAINT categories_pkey PRIMARY KEY (id); - - --- --- Name: device_tokens_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.device_tokens - ADD CONSTRAINT device_tokens_pkey PRIMARY KEY (id); - - --- --- Name: documents_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.documents - ADD CONSTRAINT documents_pkey PRIMARY KEY (id); - - --- --- Name: events_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.events - ADD CONSTRAINT events_pkey PRIMARY KEY (id); - - --- --- Name: members_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.members - ADD CONSTRAINT members_pkey PRIMARY KEY (id); - - --- --- Name: movements_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.movements - ADD CONSTRAINT movements_pkey PRIMARY KEY (id); - - --- --- Name: organizations_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.organizations - ADD CONSTRAINT organizations_pkey PRIMARY KEY (id); - - --- --- Name: posts_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.posts - ADD CONSTRAINT posts_pkey PRIMARY KEY (id); - - --- --- Name: push_notifications_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.push_notifications - ADD CONSTRAINT push_notifications_pkey PRIMARY KEY (id); - - --- --- Name: transfers_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.transfers - ADD CONSTRAINT transfers_pkey PRIMARY KEY (id); - - --- --- Name: users_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.users - ADD CONSTRAINT users_pkey PRIMARY KEY (id); - - --- --- Name: index_accounts_on_accountable_type_and_accountable_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_accounts_on_accountable_type_and_accountable_id ON public.accounts USING btree (accountable_type, accountable_id); - - --- --- Name: index_accounts_on_organization_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_accounts_on_organization_id ON public.accounts USING btree (organization_id); - - --- --- Name: index_active_admin_comments_on_author_type_and_author_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_active_admin_comments_on_author_type_and_author_id ON public.active_admin_comments USING btree (author_type, author_id); - - --- --- Name: index_active_admin_comments_on_namespace; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_active_admin_comments_on_namespace ON public.active_admin_comments USING btree (namespace); - - --- --- Name: index_active_admin_comments_on_resource_type_and_resource_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_active_admin_comments_on_resource_type_and_resource_id ON public.active_admin_comments USING btree (resource_type, resource_id); - - --- --- Name: index_device_tokens_on_user_id_and_token; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_device_tokens_on_user_id_and_token ON public.device_tokens USING btree (user_id, token); - - --- --- Name: index_documents_on_documentable_id_and_documentable_type; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_documents_on_documentable_id_and_documentable_type ON public.documents USING btree (documentable_id, documentable_type); - - --- --- Name: index_documents_on_label; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_documents_on_label ON public.documents USING btree (label); - - --- --- Name: index_events_on_member_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_events_on_member_id ON public.events USING btree (member_id) WHERE (member_id IS NOT NULL); - - --- --- Name: index_events_on_post_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_events_on_post_id ON public.events USING btree (post_id) WHERE (post_id IS NOT NULL); - - --- --- Name: index_events_on_transfer_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_events_on_transfer_id ON public.events USING btree (transfer_id) WHERE (transfer_id IS NOT NULL); - - --- --- Name: index_members_on_organization_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_members_on_organization_id ON public.members USING btree (organization_id); - - --- --- Name: index_members_on_user_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_members_on_user_id ON public.members USING btree (user_id); - - --- --- Name: index_movements_on_account_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_movements_on_account_id ON public.movements USING btree (account_id); - - --- --- Name: index_movements_on_transfer_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_movements_on_transfer_id ON public.movements USING btree (transfer_id); - - --- --- Name: index_organizations_on_name; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_organizations_on_name ON public.organizations USING btree (name); - - --- --- Name: index_posts_on_category_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_posts_on_category_id ON public.posts USING btree (category_id); - - --- --- Name: index_posts_on_organization_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_posts_on_organization_id ON public.posts USING btree (organization_id); - - --- --- Name: index_posts_on_tags; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_posts_on_tags ON public.posts USING gin (tags); - - --- --- Name: index_posts_on_tsv; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_posts_on_tsv ON public.posts USING gin (tsv); - - --- --- Name: index_posts_on_user_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_posts_on_user_id ON public.posts USING btree (user_id); - - --- --- Name: index_transfers_on_operator_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_transfers_on_operator_id ON public.transfers USING btree (operator_id); - - --- --- Name: index_transfers_on_post_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_transfers_on_post_id ON public.transfers USING btree (post_id); - - --- --- Name: index_users_on_email; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_users_on_email ON public.users USING btree (email); - - --- --- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX unique_schema_migrations ON public.schema_migrations USING btree (version); - - --- --- Name: tsvectorupdate; Type: TRIGGER; Schema: public; Owner: - --- - -CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE ON public.posts FOR EACH ROW EXECUTE PROCEDURE public.posts_trigger(); - - --- --- Name: events_member_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.events - ADD CONSTRAINT events_member_id_fkey FOREIGN KEY (member_id) REFERENCES public.members(id); - - --- --- Name: events_post_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.events - ADD CONSTRAINT events_post_id_fkey FOREIGN KEY (post_id) REFERENCES public.posts(id); - - --- --- Name: events_transfer_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.events - ADD CONSTRAINT events_transfer_id_fkey FOREIGN KEY (transfer_id) REFERENCES public.transfers(id); - - --- --- Name: fk_rails_1ceb778440; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.accounts - ADD CONSTRAINT fk_rails_1ceb778440 FOREIGN KEY (organization_id) REFERENCES public.organizations(id); - - --- --- Name: fk_rails_36fb6ef1a8; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.push_notifications - ADD CONSTRAINT fk_rails_36fb6ef1a8 FOREIGN KEY (device_token_id) REFERENCES public.device_tokens(id); - - --- --- Name: fk_rails_79a395b2d7; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.push_notifications - ADD CONSTRAINT fk_rails_79a395b2d7 FOREIGN KEY (event_id) REFERENCES public.events(id); - - --- --- PostgreSQL database dump complete --- - -SET search_path TO "$user", public; - -INSERT INTO schema_migrations (version) VALUES ('1'); - -INSERT INTO schema_migrations (version) VALUES ('2'); - -INSERT INTO schema_migrations (version) VALUES ('20121019101022'); - -INSERT INTO schema_migrations (version) VALUES ('20121104004639'); - -INSERT INTO schema_migrations (version) VALUES ('20121104085711'); - -INSERT INTO schema_migrations (version) VALUES ('20121121233818'); - -INSERT INTO schema_migrations (version) VALUES ('20130214175758'); - -INSERT INTO schema_migrations (version) VALUES ('20130214181128'); - -INSERT INTO schema_migrations (version) VALUES ('20130222185624'); - -INSERT INTO schema_migrations (version) VALUES ('20130425165150'); - -INSERT INTO schema_migrations (version) VALUES ('20130508085004'); - -INSERT INTO schema_migrations (version) VALUES ('20130513092219'); - -INSERT INTO schema_migrations (version) VALUES ('20130514094755'); - -INSERT INTO schema_migrations (version) VALUES ('20130618210236'); - -INSERT INTO schema_migrations (version) VALUES ('20130621102219'); - -INSERT INTO schema_migrations (version) VALUES ('20130621103053'); - -INSERT INTO schema_migrations (version) VALUES ('20130621103501'); - -INSERT INTO schema_migrations (version) VALUES ('20130621105452'); - -INSERT INTO schema_migrations (version) VALUES ('20130703233851'); - -INSERT INTO schema_migrations (version) VALUES ('20130703234011'); - -INSERT INTO schema_migrations (version) VALUES ('20130703234042'); - -INSERT INTO schema_migrations (version) VALUES ('20130723160206'); - -INSERT INTO schema_migrations (version) VALUES ('20131017144321'); - -INSERT INTO schema_migrations (version) VALUES ('20131025202608'); - -INSERT INTO schema_migrations (version) VALUES ('20131027215517'); - -INSERT INTO schema_migrations (version) VALUES ('20131029202724'); - -INSERT INTO schema_migrations (version) VALUES ('20131103221044'); - -INSERT INTO schema_migrations (version) VALUES ('20131104004235'); - -INSERT INTO schema_migrations (version) VALUES ('20131104013634'); - -INSERT INTO schema_migrations (version) VALUES ('20131104013829'); - -INSERT INTO schema_migrations (version) VALUES ('20131104032622'); - -INSERT INTO schema_migrations (version) VALUES ('20131220160257'); - -INSERT INTO schema_migrations (version) VALUES ('20131227110122'); - -INSERT INTO schema_migrations (version) VALUES ('20131227142805'); - -INSERT INTO schema_migrations (version) VALUES ('20131227155440'); - -INSERT INTO schema_migrations (version) VALUES ('20131231110424'); - -INSERT INTO schema_migrations (version) VALUES ('20140119161433'); - -INSERT INTO schema_migrations (version) VALUES ('20140513141718'); - -INSERT INTO schema_migrations (version) VALUES ('20140514225527'); - -INSERT INTO schema_migrations (version) VALUES ('20150329193421'); - -INSERT INTO schema_migrations (version) VALUES ('20150330200315'); - -INSERT INTO schema_migrations (version) VALUES ('20150422162806'); - -INSERT INTO schema_migrations (version) VALUES ('20180221161343'); - -INSERT INTO schema_migrations (version) VALUES ('20180501093846'); - -INSERT INTO schema_migrations (version) VALUES ('20180514193153'); - -INSERT INTO schema_migrations (version) VALUES ('20180524143938'); - -INSERT INTO schema_migrations (version) VALUES ('20180525141138'); - -INSERT INTO schema_migrations (version) VALUES ('20180529144243'); - -INSERT INTO schema_migrations (version) VALUES ('20180530180546'); - -INSERT INTO schema_migrations (version) VALUES ('20180604145622'); - -INSERT INTO schema_migrations (version) VALUES ('20180828160700'); - -INSERT INTO schema_migrations (version) VALUES ('20180831161349'); - -INSERT INTO schema_migrations (version) VALUES ('20180924164456'); - -INSERT INTO schema_migrations (version) VALUES ('20181004200104'); - -INSERT INTO schema_migrations (version) VALUES ('20190319121401'); - -INSERT INTO schema_migrations (version) VALUES ('20190322180602'); - -INSERT INTO schema_migrations (version) VALUES ('20190411192828'); - -INSERT INTO schema_migrations (version) VALUES ('20190412163011'); - -INSERT INTO schema_migrations (version) VALUES ('20190523213421'); - -INSERT INTO schema_migrations (version) VALUES ('20190523225323'); - diff --git a/lib/tasks/elasticsearch.rake b/lib/tasks/elasticsearch.rake new file mode 100644 index 000000000..744fd91a7 --- /dev/null +++ b/lib/tasks/elasticsearch.rake @@ -0,0 +1 @@ +require 'elasticsearch/rails/tasks/import' diff --git a/spec/controllers/offers_controller_spec.rb b/spec/controllers/offers_controller_spec.rb index 9eccf526d..4f1db8ecf 100644 --- a/spec/controllers/offers_controller_spec.rb +++ b/spec/controllers/offers_controller_spec.rb @@ -12,12 +12,6 @@ organization: organization, category: test_category) end - let!(:other_offer) do - Fabricate(:offer, - user: another_member.user, - organization: organization, - category: test_category) - end include_context "stub browser locale" @@ -28,99 +22,40 @@ it "populates an array of offers" do login(another_member.user) - get :index - - expect(assigns(:offers)).to eq([other_offer, offer]) - end - - context "when one offer is not active" do - before do - other_offer.active = false - other_offer.save! - end - - it "only returns active offers" do - login(another_member.user) - - get :index - - expect(assigns(:offers)).to eq([offer]) - end - end - - context "when one offer's user is not active" do - before do - member.active = false - member.save! - end - - it "only returns offers from active users" do - login(another_member.user) - - get :index - - expect(assigns(:offers)).to eq([other_offer]) - end + get "index" + expect(assigns(:offers)).to eq([offer]) end end context "with another organization" do it "skips the original org's offers" do login(yet_another_member.user) - - get :index - + get "index" expect(assigns(:offers)).to eq([]) end end end describe "GET #index (search)" do - before { login(another_member.user) } before do - offer.title = "Queridos compañeros" - offer.save! - end - - it "populates an array of offers" do - get :index, q: 'compañeros' - - expect(assigns(:offers)).to eq([offer]) - end - - it "allows to search by partial word" do - get :index, q: 'compañ' - - expect(assigns(:offers)).to eq([offer]) - end - - context "when one offer is not active" do - before do - other_offer.active = false - other_offer.save! - end - - it "only returns active offers" do - login(another_member.user) + Offer.__elasticsearch__.create_index!(force: true) - get :index - - expect(assigns(:offers)).to eq([offer]) - end + # Import any already existing model into the index + # for instance the ones that have been created in upper + # `let!` or `before` blocks + Offer.__elasticsearch__.import(force: true, refresh: true) end - context "when one offer's user is not active" do - before do - member.active = false - member.save! - end - - it "only returns offers from active users" do - login(another_member.user) + it "populates an array of offers" do + login(another_member.user) - get :index + get "index", q: offer.title.split(/\s/).first - expect(assigns(:offers)).to eq([other_offer]) - end + # @offers is a wrapper from Elasticsearch. It's iterator-equivalent to + # the underlying query from the database. + expect(assigns(:offers)).to be_a Elasticsearch::Model::Response::Records + expect(assigns(:offers).size).to eq 1 + expect(assigns(:offers)[0]).to eq offer + expect(assigns(:offers).to_a).to eq([offer]) end end From 73e62900fb93f724518cf12cfb3f3466ff1e0958 Mon Sep 17 00:00:00 2001 From: enricostano Date: Fri, 20 Sep 2019 13:39:02 +0200 Subject: [PATCH 15/33] Fix Gemfile.lock --- Gemfile.lock | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index 00e7aed0f..36da5a6ed 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -145,6 +145,8 @@ GEM fabrication (2.11.3) faker (1.9.3) i18n (>= 0.7) + faraday (0.9.1) + multipart-post (>= 1.2, < 3) formtastic (3.1.5) actionpack (>= 3.2.13) formtastic_i18n (0.6.0) From cb28bce4c6b3a7c8fd562fe35fa09ed1ad497479 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Sat, 25 May 2019 01:32:36 +0200 Subject: [PATCH 16/33] Ubuntu Bionic --- .ruby-version | 2 +- Gemfile | 2 +- Gemfile.lock | 78 ++++++++++++++++++++++----------------------- config/database.yml | 2 +- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/.ruby-version b/.ruby-version index 276cbf9e2..0cadbc1e3 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.3.0 +2.5.5 diff --git a/Gemfile b/Gemfile index 811334e20..f8b962925 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,7 @@ gem "rdiscount" gem 'activeadmin', '~> 1.2.1' gem 'has_scope' gem 'pundit', '~> 2.0.0' -gem 'pg', '0.17.1' +gem 'pg', '0.21.0' gem 'hstore_translate' gem 'dalli' gem 'devise', '~> 4.5.0' diff --git a/Gemfile.lock b/Gemfile.lock index 36da5a6ed..ff62bb0b1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,21 +1,21 @@ GEM remote: https://rubygems.org/ specs: - actionmailer (4.2.11) - actionpack (= 4.2.11) - actionview (= 4.2.11) - activejob (= 4.2.11) + actionmailer (4.2.11.1) + actionpack (= 4.2.11.1) + actionview (= 4.2.11.1) + activejob (= 4.2.11.1) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 1.0, >= 1.0.5) - actionpack (4.2.11) - actionview (= 4.2.11) - activesupport (= 4.2.11) + actionpack (4.2.11.1) + actionview (= 4.2.11.1) + activesupport (= 4.2.11.1) rack (~> 1.6) rack-test (~> 0.6.2) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (4.2.11) - activesupport (= 4.2.11) + actionview (4.2.11.1) + activesupport (= 4.2.11.1) builder (~> 3.1) erubis (~> 2.7.0) rails-dom-testing (~> 1.0, >= 1.0.5) @@ -32,17 +32,17 @@ GEM ransack (~> 1.3) sass (~> 3.1) sprockets (< 4.1) - activejob (4.2.11) - activesupport (= 4.2.11) + activejob (4.2.11.1) + activesupport (= 4.2.11.1) globalid (>= 0.3.0) - activemodel (4.2.11) - activesupport (= 4.2.11) + activemodel (4.2.11.1) + activesupport (= 4.2.11.1) builder (~> 3.1) - activerecord (4.2.11) - activemodel (= 4.2.11) - activesupport (= 4.2.11) + activerecord (4.2.11.1) + activemodel (= 4.2.11.1) + activesupport (= 4.2.11.1) arel (~> 6.0) - activesupport (4.2.11) + activesupport (4.2.11.1) i18n (~> 0.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) @@ -104,7 +104,7 @@ GEM execjs coffee-script-source (1.8.0) columnize (0.9.0) - concurrent-ruby (1.1.3) + concurrent-ruby (1.1.5) connection_pool (2.2.1) crass (1.0.4) dalli (2.7.2) @@ -151,7 +151,7 @@ GEM actionpack (>= 3.2.13) formtastic_i18n (0.6.0) gli (2.16.0) - globalid (0.4.1) + globalid (0.4.2) activesupport (>= 4.2.0) has_scope (0.6.0) actionpack (>= 3.2, < 5) @@ -205,7 +205,7 @@ GEM mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) mini_mime (1.0.1) - mini_portile2 (2.3.0) + mini_portile2 (2.4.0) minitest (5.11.3) multi_json (1.11.2) multipart-post (2.0.0) @@ -213,14 +213,14 @@ GEM net-ssh (>= 2.6.5) net-ssh (2.9.2) netrc (0.11.0) - nokogiri (1.8.5) - mini_portile2 (~> 2.3.0) + nokogiri (1.10.3) + mini_portile2 (~> 2.4.0) orm_adapter (0.5.0) parallel (1.12.1) parser (2.5.0.0) ast (~> 2.4.0) pdf-core (0.7.0) - pg (0.17.1) + pg (0.21.0) polyamorous (1.3.3) activerecord (>= 3.0) powerpack (0.1.1) @@ -237,16 +237,16 @@ GEM rack rack-test (0.6.3) rack (>= 1.0) - rails (4.2.11) - actionmailer (= 4.2.11) - actionpack (= 4.2.11) - actionview (= 4.2.11) - activejob (= 4.2.11) - activemodel (= 4.2.11) - activerecord (= 4.2.11) - activesupport (= 4.2.11) + rails (4.2.11.1) + actionmailer (= 4.2.11.1) + actionpack (= 4.2.11.1) + actionview (= 4.2.11.1) + activejob (= 4.2.11.1) + activemodel (= 4.2.11.1) + activerecord (= 4.2.11.1) + activesupport (= 4.2.11.1) bundler (>= 1.3.0, < 2.0) - railties (= 4.2.11) + railties (= 4.2.11.1) sprockets-rails rails-deprecated_sanitizer (1.0.3) activesupport (>= 4.2.0.alpha) @@ -259,14 +259,14 @@ GEM rails-i18n (4.0.3) i18n (~> 0.6) railties (~> 4.0) - railties (4.2.11) - actionpack (= 4.2.11) - activesupport (= 4.2.11) + railties (4.2.11.1) + actionpack (= 4.2.11.1) + activesupport (= 4.2.11.1) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rainbow (3.0.0) raindrops (0.16.0) - rake (12.3.1) + rake (12.3.2) ransack (1.8.6) actionpack (>= 3.0) activerecord (>= 3.0) @@ -420,7 +420,7 @@ DEPENDENCIES kaminari (~> 1.1.1) letter_opener (= 1.4.1) localeapp (= 2.1.1) - pg (= 0.17.1) + pg (= 0.21.0) prawn (~> 2.2.0) prawn-table (~> 0.2.2) pundit (~> 2.0.0) @@ -447,7 +447,7 @@ DEPENDENCIES whenever RUBY VERSION - ruby 2.3.0p0 + ruby 2.5.5p157 BUNDLED WITH - 1.16.2 + 1.17.3 diff --git a/config/database.yml b/config/database.yml index 61b9c86f2..590d9d50e 100644 --- a/config/database.yml +++ b/config/database.yml @@ -16,7 +16,7 @@ defaults: &defaults collation: 'es_ES.UTF-8' ctype: 'es_ES.UTF-8' template: 'template0' - encoding: utf8 + encoding: 'UTF8' development: <<: *defaults From 48e8cfd7a9ba57413d609ee27eebb9074f3624c9 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Sat, 25 May 2019 02:01:28 +0200 Subject: [PATCH 17/33] Install correct Bundler version on Travis CI --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0b4232a41..f1b1db71f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ env: - DATABASE_URL=postgres://postgres@localhost/timeoverflow_test - CC_TEST_REPORTER_ID=025bc15a0fa9afa52d86ee24fea845cf1d363f48a466bcf2cef8ab80c29acb28 before_install: - - gem install bundler:1.17.0 + - gem install bundler:1.17.3 before_script: - bundle exec rake db:setup - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter From 7b9cc703a0eebf922fab20d2c7dfeba002b36c1a Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Sat, 25 May 2019 17:23:11 +0200 Subject: [PATCH 18/33] update to Ruby 2.6 (we need to monkeypatch ActionController::TestResponse to make tests work with the combo Rails 4.2 & Ruby 2.6) --- .ruby-version | 2 +- Gemfile.lock | 2 +- spec/spec_helper.rb | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/.ruby-version b/.ruby-version index 0cadbc1e3..ec1cf33c3 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.5.5 +2.6.3 diff --git a/Gemfile.lock b/Gemfile.lock index ff62bb0b1..ef6705fb3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -447,7 +447,7 @@ DEPENDENCIES whenever RUBY VERSION - ruby 2.5.5p157 + ruby 2.6.3p62 BUNDLED WITH 1.17.3 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 44cd48558..daa6c289b 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -157,3 +157,20 @@ def set_browser_locale(locale) with.library :rails end end + +# Rails 4.2 call `initialize` inside `recycle!`. However Ruby 2.6 doesn't allow calling `initialize` twice. +# More info: https://github.com/rails/rails/issues/34790 +if Rails.version < "5" + module ActionController + class TestResponse < ActionDispatch::TestResponse + def recycle! + # hack to avoid MonitorMixin double-initialize error + @mon_mutex_owner_object_id = nil + @mon_mutex = nil + initialize + end + end + end +else + puts "⚠ Monkeypatch for ActionController::TestResponse no longer needed! Remove me please!" +end From 55a0df7dd621417ea8d9e336cb8adf67ea224bfb Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Thu, 19 Sep 2019 17:22:36 +0200 Subject: [PATCH 19/33] Use Ubuntu Bionic in Travis CI --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f1b1db71f..b76baa98c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: ruby -dist: trusty +dist: bionic cache: bundler bundler_args: '--without development' env: From 0c6cc12b17b63681574f7163f5d637bcc3854cb4 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 19 Sep 2019 18:23:51 +0200 Subject: [PATCH 20/33] Update .travis.yml --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index b76baa98c..64f6c7967 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,10 @@ language: ruby dist: bionic cache: bundler +services: + - postgresql +addons: + postgresql: "10.10" bundler_args: '--without development' env: global: From 59ff1fea200128e87389941f91dd7e04a009d82f Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 19 Sep 2019 18:30:58 +0200 Subject: [PATCH 21/33] Update .travis.yml --- .travis.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 64f6c7967..a91eeea7d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,10 @@ dist: bionic cache: bundler services: - postgresql + - elasticsearch addons: postgresql: "10.10" + chrome: stable bundler_args: '--without development' env: global: @@ -21,7 +23,3 @@ before_script: - sleep 10 after_script: - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT -services: - - elasticsearch -addons: - chrome: stable From 089c073ec8464ecb27a27e44c41cfd33da4cb2fc Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 19 Sep 2019 18:39:51 +0200 Subject: [PATCH 22/33] Update .travis.yml --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a91eeea7d..4862e5c93 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,11 @@ services: - postgresql - elasticsearch addons: - postgresql: "10.10" + postgresql: "10" + apt: + packages: + - postgresql-10 + - postgresql-client-10 chrome: stable bundler_args: '--without development' env: From ae4e3ab60458e0fb9dd31fc3342d164e69dbe45b Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 20 Sep 2019 15:39:58 +0200 Subject: [PATCH 23/33] Use production's PostgreSQL version in CI --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4862e5c93..082cb72fe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,11 +5,11 @@ services: - postgresql - elasticsearch addons: - postgresql: "10" + postgresql: "9.4" apt: packages: - - postgresql-10 - - postgresql-client-10 + - postgresql-9.4 + - postgresql-client-9.4 chrome: stable bundler_args: '--without development' env: From 5b6bfab907ed353a755d1dde4bbe3c2f593bfd9f Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 20 Sep 2019 19:06:51 +0200 Subject: [PATCH 24/33] Update Capistrano from 3.4.0 to 3.4.1 I got the following strange error ``` /home/timeoverflow/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/net-ssh-2.9.2/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb:118:in `generate_key': undefined method `p=' fo r # (NoMethodError) Did you mean? p (Backtrace restricted to imported tasks) cap aborted! NoMethodError: undefined method `p=' for # Did you mean? p ``` and updating fixed it. --- Gemfile.lock | 12 ++++++------ config/deploy.rb | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index ef6705fb3..0e5810de5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -71,7 +71,7 @@ GEM builder (3.2.3) byebug (4.0.5) columnize (= 0.9.0) - capistrano (3.4.0) + capistrano (3.4.1) i18n rake (>= 10.0.0) sshkit (~> 1.3) @@ -209,9 +209,9 @@ GEM minitest (5.11.3) multi_json (1.11.2) multipart-post (2.0.0) - net-scp (1.2.1) - net-ssh (>= 2.6.5) - net-ssh (2.9.2) + net-scp (2.0.0) + net-ssh (>= 2.6.5, < 6.0.0) + net-ssh (5.2.0) netrc (0.11.0) nokogiri (1.10.3) mini_portile2 (~> 2.4.0) @@ -266,7 +266,7 @@ GEM thor (>= 0.18.1, < 2.0) rainbow (3.0.0) raindrops (0.16.0) - rake (12.3.2) + rake (12.3.3) ransack (1.8.6) actionpack (>= 3.0) activerecord (>= 3.0) @@ -354,7 +354,7 @@ GEM actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) - sshkit (1.8.1) + sshkit (1.20.0) net-scp (>= 1.1.2) net-ssh (>= 2.8.0) thor (0.20.3) diff --git a/config/deploy.rb b/config/deploy.rb index d842d9643..cfe7362b2 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -1,5 +1,5 @@ # config valid only for current version of Capistrano -lock '3.4.0' +lock '3.4.1' set :application, 'timeoverflow' set :repo_url, 'git@github.com:coopdevs/timeoverflow.git' From 4bfbeed2731eb450b7e72e091c77415c3dee89a1 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Mon, 7 Oct 2019 14:59:46 +0200 Subject: [PATCH 25/33] Remove plpgsql PostgreSQL extension It was added in the very beginning of the project in commit `e37eb7d` but it doesn't seem to be used anywhere. Leftovers of an old copy-paste? --- db/schema.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index bfcd9e381..a619fd84d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -14,7 +14,6 @@ ActiveRecord::Schema.define(version: 20190412163011) do # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" enable_extension "hstore" enable_extension "pg_trgm" From 4392df1345d6e65031c5bb49f1d4213a4cffe271 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Mon, 7 Oct 2019 15:01:02 +0200 Subject: [PATCH 26/33] Remove pg_trgm PostgreSQL extension No need to install this extension used by full-text search until we don't replace ElasticSearch with it. Still, it was added in `f514c35` in the early days (2013) for user search but it doesn't seem to be used. You @enricostano and @markets might now better. --- db/schema.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index bfcd9e381..e2d2de5d1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -16,7 +16,6 @@ # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" enable_extension "hstore" - enable_extension "pg_trgm" create_table "accounts", force: :cascade do |t| t.integer "accountable_id" From a84e05acb0b400e9b8620dc6c4b87dcdb64a5558 Mon Sep 17 00:00:00 2001 From: amyhenning Date: Sat, 12 Oct 2019 11:53:33 -0500 Subject: [PATCH 27/33] Add spec for brand logo case when no user is signed in --- spec/features/brand_logo_spec.rb | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/spec/features/brand_logo_spec.rb b/spec/features/brand_logo_spec.rb index bd89399f3..9420715a6 100644 --- a/spec/features/brand_logo_spec.rb +++ b/spec/features/brand_logo_spec.rb @@ -39,3 +39,23 @@ end end +RSpec.feature 'sign out' do + let!(:user) do + Fabricate( + :user, + email: 'user@timeoverflow.org', + password: 'papapa22', + terms_accepted_at: 1.day.from_now + ) + end + + context 'without a user' do + it 'does not render the logo' do + sign_in_with(user.email, user.password) + click_link user.email + click_link I18n.t('application.navbar.sign_out') + + expect(page).to have_no_css('.organization-brand-logo') + end + end +end From 9e525c09a195c69c70abd930003d2d4ca67ae73f Mon Sep 17 00:00:00 2001 From: Andrey Leontev Date: Wed, 23 Oct 2019 14:39:35 +1000 Subject: [PATCH 28/33] improve readability --- spec/controllers/inquiries_controller_spec.rb | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/spec/controllers/inquiries_controller_spec.rb b/spec/controllers/inquiries_controller_spec.rb index 694be650f..3a36c693b 100644 --- a/spec/controllers/inquiries_controller_spec.rb +++ b/spec/controllers/inquiries_controller_spec.rb @@ -1,17 +1,19 @@ require "spec_helper" RSpec.describe InquiriesController do - let (:test_organization) { Fabricate(:organization) } - let (:member) { Fabricate(:member, organization: test_organization) } - let (:another_member) { Fabricate(:member, organization: test_organization) } - let (:test_category) { Fabricate(:category) } - let! (:inquiry) do + let(:test_organization) { Fabricate(:organization) } + let(:member) { Fabricate(:member, organization: test_organization) } + let(:another_member) { Fabricate(:member, organization: test_organization) } + let(:test_category) { Fabricate(:category) } + let!(:inquiry) do Fabricate(:inquiry, user: member.user, organization: test_organization, category: test_category) end + include_context "stub browser locale" + before { set_browser_locale("ca") } describe "GET #index" do @@ -27,7 +29,7 @@ describe "GET #show" do context "with valid params" do - context "with a logged user" do + context "with a logged user" do it "assigns the requested inquiry to @inquiry" do login(another_member.user) @@ -40,10 +42,10 @@ describe "POST #create" do context "with valid params" do - context "with a logged user" do + context "with a logged user" do it "creates a new inquiry" do login(another_member.user) - + expect do post "create", inquiry: { user: another_member.user, category_id: test_category.id, @@ -57,16 +59,14 @@ describe "PUT #update" do context "with valid params" do context "with a logged user" do + before { login(another_member.user) } + it "located the requested @inquiry" do - login(member.user) - put "update", id: inquiry.id, inquiry: Fabricate.to_params(:inquiry) expect(assigns(:inquiry)).to eq(inquiry) end it "changes @inquiry's attributes" do - login(member.user) - put "update", id: inquiry.id, inquiry: Fabricate.to_params(:inquiry, @@ -84,9 +84,9 @@ end context "with invalid params" do - context "with a logged user" do + context "with a logged user" do it "does not change @inquiry's attributes" do - login(member.user) + login(another_member.user) put :update, id: inquiry.id, @@ -103,9 +103,9 @@ end describe "DELETE destroy" do + before { login(another_member.user) } + it "toggle active field" do - login(member.user) - delete :destroy, id: inquiry.id inquiry.reload @@ -113,8 +113,6 @@ end it "redirects to inquiries#index" do - login(member.user) - delete :destroy, id: inquiry.id expect(response).to redirect_to inquiries_url end From 13f6a8ed61d626145d4a885da4150093f607cdb1 Mon Sep 17 00:00:00 2001 From: Andrey Leontev Date: Thu, 24 Oct 2019 11:31:47 +1000 Subject: [PATCH 29/33] fix syntax --- spec/controllers/inquiries_controller_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/controllers/inquiries_controller_spec.rb b/spec/controllers/inquiries_controller_spec.rb index 3a36c693b..2827e450a 100644 --- a/spec/controllers/inquiries_controller_spec.rb +++ b/spec/controllers/inquiries_controller_spec.rb @@ -59,7 +59,7 @@ describe "PUT #update" do context "with valid params" do context "with a logged user" do - before { login(another_member.user) } + before { login(member.user) } it "located the requested @inquiry" do put "update", id: inquiry.id, inquiry: Fabricate.to_params(:inquiry) @@ -86,7 +86,7 @@ context "with invalid params" do context "with a logged user" do it "does not change @inquiry's attributes" do - login(another_member.user) + login(member.user) put :update, id: inquiry.id, @@ -103,7 +103,7 @@ end describe "DELETE destroy" do - before { login(another_member.user) } + before { login(member.user) } it "toggle active field" do delete :destroy, id: inquiry.id From ade9dfd1ef7a22c6e4101796d5713a178bf6736a Mon Sep 17 00:00:00 2001 From: Andrey Leontev Date: Fri, 25 Oct 2019 10:23:47 +1000 Subject: [PATCH 30/33] remove trailing spaces --- spec/controllers/inquiries_controller_spec.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/controllers/inquiries_controller_spec.rb b/spec/controllers/inquiries_controller_spec.rb index 2827e450a..495c13a4f 100644 --- a/spec/controllers/inquiries_controller_spec.rb +++ b/spec/controllers/inquiries_controller_spec.rb @@ -29,7 +29,7 @@ describe "GET #show" do context "with valid params" do - context "with a logged user" do + context "with a logged user" do it "assigns the requested inquiry to @inquiry" do login(another_member.user) @@ -45,7 +45,6 @@ context "with a logged user" do it "creates a new inquiry" do login(another_member.user) - expect do post "create", inquiry: { user: another_member.user, category_id: test_category.id, From 268bc0dfd27778a7416808d3c1462a1fde9a64b2 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Tue, 19 Nov 2019 18:29:41 +0100 Subject: [PATCH 31/33] Add next.timeoverflow.org Capistrano deploy This is the upgraded server we are setting up to host the app. Time to deploy and start testing! :tada: The Capistrano environment is tightly coupled with Rails environments so we need to add a new one called `next`. --- Capfile | 2 +- config/database.yml | 4 ++ config/deploy/next.rb | 1 + config/environments/next.rb | 98 +++++++++++++++++++++++++++++++++++++ config/secrets.yml | 3 ++ 5 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 config/deploy/next.rb create mode 100644 config/environments/next.rb diff --git a/Capfile b/Capfile index da85f9d98..961d5b90b 100644 --- a/Capfile +++ b/Capfile @@ -18,7 +18,7 @@ require 'capistrano/deploy' require 'capistrano/rails' stage = ARGV.first -if stage == 'staging' # Sorry, production is not ready yet +if stage != 'production' # Sorry, production is not ready yet require 'capistrano/rbenv' end diff --git a/config/database.yml b/config/database.yml index 590d9d50e..83e46dd15 100644 --- a/config/database.yml +++ b/config/database.yml @@ -33,3 +33,7 @@ staging: production: # Set DATABASE_URL environment variable url: <%= ENV['DATABASE_URL'] %> + +next: + <<: *defaults + database: <%= ENV.fetch('DATABASE_NAME', 'timeoverflow_production') %> diff --git a/config/deploy/next.rb b/config/deploy/next.rb new file mode 100644 index 000000000..6b603eb07 --- /dev/null +++ b/config/deploy/next.rb @@ -0,0 +1 @@ +server 'next.timeoverflow.org', user: 'timeoverflow', roles: %w(app db web) diff --git a/config/environments/next.rb b/config/environments/next.rb new file mode 100644 index 000000000..1ba241c29 --- /dev/null +++ b/config/environments/next.rb @@ -0,0 +1,98 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.cache_classes = true + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Enable Rack::Cache to put a simple HTTP cache in front of your application + # Add `rack-cache` to your Gemfile before enabling this. + # For large-scale production use, consider using a caching reverse proxy like + # NGINX, varnish or squid. + # config.action_dispatch.rack_cache = true + + # Disable serving static files from the `/public` folder by default since + # Apache or NGINX already handles this. + config.serve_static_files = true + + # Compress JavaScripts and CSS. + config.assets.js_compressor = :uglifier + # config.assets.css_compressor = :sass + + # Do not fallback to assets pipeline if a precompiled asset is missed. + config.assets.compile = true # false + + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. + config.assets.digest = true + + # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb + + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + config.force_ssl = true + + # Use the lowest log level to ensure availability of diagnostic information + # when problems arise. + config.log_level = :debug + + # Prepend all log lines with the following tags. + # config.log_tags = [ :subdomain, :uuid ] + + # Use a different logger for distributed setups. + # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) + + # Use a different cache store in production. + # config.cache_store = :mem_cache_store + config.cache_store = :dalli_store + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.action_controller.asset_host = 'http://assets.example.com' + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + config.action_mailer.raise_delivery_errors = true + + config.action_mailer.delivery_method = :smtp + config.action_mailer.default_url_options = { + host: ENV["MAIL_LINK_HOST"], + protocol: (ENV["MAIL_LINK_PROTO"] || "https") + } + + # Retrieve SMTP configuration from environment variables + # starting with `SMTP_` + smtp_env = Hash[ENV.map do |k,v| + if /^SMTP_(.*)$/ === k + [$1.downcase.to_sym, YAML.load(v)] + end + end.compact] + + if smtp_env.present? + config.action_mailer.smtp_settings = smtp_env + end + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Send deprecation notices to registered listeners. + config.active_support.deprecation = :notify + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false +end diff --git a/config/secrets.yml b/config/secrets.yml index f915c5e4c..8dc976e9c 100644 --- a/config/secrets.yml +++ b/config/secrets.yml @@ -9,3 +9,6 @@ staging: production: secret_key_base: <%= ENV['SECRET_TOKEN'] %> + +next: + secret_key_base: <%= ENV['SECRET_TOKEN'] %> From 05dcbdceee22680d32015f73141e26f949b6f269 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Wed, 20 Nov 2019 19:06:27 +0100 Subject: [PATCH 32/33] Run db:schema:load when deploying with COLD=1 This needed when deploying to a server for the first time or when you want to wipe out a database. The issue I'm fixing is this. Things have evolved and in https://github.com/coopdevs/timeoverflow-provisioning we no longer set things up to enable PostgreSQL extensions such as `pg_trgm`. Because Capistrano runs `db:migrate` when deploying very old migrations like `db/migrate/00000000000002_setup_pg_trgm.rb` don't work anymore. I prefer to make this step explicit in the code and with some context rather than having to do this manually in the server and let the dev in charge figure it out every time. Apparently, from https://github.com/capistrano/rails/issues/118 I see this is a known issue for which there's no provided solution. I copied a solution proposed by a capistrano/rails member so should be good. Just run it as follows: ``` $ bundle exec cap staging deploy COLD=1 ``` --- config/deploy.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/config/deploy.rb b/config/deploy.rb index cfe7362b2..eb4d44cf7 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -57,3 +57,14 @@ end end end + +task "deploy:db:load" do + on primary :db do + within release_path do + with rails_env: fetch(:rails_env) do + execute :rake, "db:schema:load" + end + end + end +end +before "deploy:migrate", "deploy:db:load" if ENV["COLD"] From 5261bce8dea571e71a59a85ca0fcf17fce329336 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Wed, 4 Dec 2019 10:19:03 +0100 Subject: [PATCH 33/33] Do not reinstall PostgreSQL 9.4 It comes installed in Travis CI boxes. This might fix the service start, which is currently timing out. See details: https://github.com/coopdevs/timeoverflow/pull/525#issuecomment-561546558 --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 082cb72fe..f94dd3699 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,10 +6,6 @@ services: - elasticsearch addons: postgresql: "9.4" - apt: - packages: - - postgresql-9.4 - - postgresql-client-9.4 chrome: stable bundler_args: '--without development' env: