Skip to content

Commit

Permalink
Merge pull request #46 from malparty/feature/list-keywords-backend
Browse files Browse the repository at this point in the history
[#26] [BackEnd] As a User, I can see a list of my previous keywords
  • Loading branch information
malparty committed Jun 30, 2021
2 parents e6f0fb8 + 7cbce3b commit 5a3282a
Show file tree
Hide file tree
Showing 17 changed files with 375 additions and 10 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Expand Up @@ -7,7 +7,7 @@ gem 'pg' # Use Postgresql as database
gem 'puma' # Use Puma as the app server
gem 'mini_magick' # A ruby wrapper for ImageMagick or GraphicsMagick command line
gem 'pagy' # A pagination gem that is very light and fast
gem 'paranoia' # Paranoia is a re-implementation of acts_as_paranoid for Rails 3 and Rails 4. Soft-deletion of records
gem 'discard' # Soft deletes for ActiveRecord
gem 'ffaker' # A library for generating fake data such as names, addresses, and phone numbers.
gem 'fabrication' # Fabrication generates objects in Ruby. Fabricators are schematics for your objects, and can be created as needed anywhere in your app or specs.
gem 'sidekiq' # background processing for Ruby
Expand Down
6 changes: 3 additions & 3 deletions Gemfile.lock
Expand Up @@ -157,6 +157,8 @@ GEM
responders
warden (~> 1.2.3)
diff-lcs (1.4.4)
discard (1.2.0)
activerecord (>= 4.2, < 7)
docile (1.4.0)
doorkeeper (5.5.1)
railties (>= 5)
Expand Down Expand Up @@ -247,8 +249,6 @@ GEM
orm_adapter (0.5.0)
pagy (3.13.0)
parallel (1.20.1)
paranoia (2.4.3)
activerecord (>= 4.0, < 6.2)
parser (3.0.1.1)
ast (~> 2.4.1)
pg (1.2.3)
Expand Down Expand Up @@ -493,6 +493,7 @@ DEPENDENCIES
danger-undercover
database_cleaner
devise
discard
doorkeeper
fabrication
ffaker
Expand All @@ -506,7 +507,6 @@ DEPENDENCIES
listen (= 3.1.5)
mini_magick
pagy
paranoia
pg
pry-byebug
pry-rails
Expand Down
16 changes: 15 additions & 1 deletion app/controllers/keywords_controller.rb
@@ -1,5 +1,19 @@
# frozen_string_literal: true

class KeywordsController < ApplicationController
def index; end
include Pagy::Backend

def index
pagy, keywords_list = pagy(keywords)

render locals: {
pagy: pagy, keywords: keywords_list
}
end

private

def keywords
KeywordsQuery.new(current_user).call
end
end
16 changes: 16 additions & 0 deletions app/controllers/registrations_controller.rb
@@ -0,0 +1,16 @@
# frozen_string_literal: true

class RegistrationsController < Devise::RegistrationsController
# Override user hard-delete (from Devise) with user soft-delete
def destroy
resource.discard

Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)

set_flash_message :notice, :destroyed

yield resource if block_given?

respond_with_navigational(resource) { redirect_to after_sign_out_path_for(resource_name) }
end
end
11 changes: 11 additions & 0 deletions app/models/keyword.rb
@@ -0,0 +1,11 @@
# frozen_string_literal: true

class Keyword < ApplicationRecord
include Discard::Model

validates :name, presence: true, length: { maximum: 255 }

belongs_to :user, inverse_of: :keywords

default_scope -> { kept }
end
6 changes: 6 additions & 0 deletions app/models/user.rb
@@ -1,6 +1,12 @@
# frozen_string_literal: true

class User < ApplicationRecord
include Discard::Model

has_many :keywords, inverse_of: :user, dependent: :destroy

default_scope -> { kept }

# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
Expand Down
19 changes: 19 additions & 0 deletions app/queries/keywords_query.rb
@@ -0,0 +1,19 @@
# frozen_string_literal: true

class KeywordsQuery
def initialize(user)
@keywords = user.keywords
end

def call
order_by_name
end

private

attr_reader :keywords

def order_by_name
keywords.order(:name)
end
end
181 changes: 181 additions & 0 deletions config/initializers/pagy.rb
@@ -0,0 +1,181 @@
# frozen_string_literal: true

# Pagy initializer file (4.10.1)
# Customize only what you really need and notice that Pagy works also without any of the following lines.
# Should you just cherry pick part of this file, please maintain the require-order of the extras


# Pagy Variables
# See https://ddnexus.github.io/pagy/api/pagy#variables
# All the Pagy::VARS are set for all the Pagy instances but can be overridden
# per instance by just passing them to Pagy.new or the #pagy controller method


# Instance variables
# See https://ddnexus.github.io/pagy/api/pagy#instance-variables
# Pagy::VARS[:page] = 1 # default
Pagy::VARS[:items] = 50
# Pagy::VARS[:outset] = 0 # default


# Other Variables
# See https://ddnexus.github.io/pagy/api/pagy#other-variables
# Pagy::VARS[:size] = [1,4,4,1] # default
# Pagy::VARS[:page_param] = :page # default
# Pagy::VARS[:params] = {} # default
# Pagy::VARS[:fragment] = '#fragment' # example
# Pagy::VARS[:link_extra] = 'data-remote="true"' # example
# Pagy::VARS[:i18n_key] = 'pagy.item_name' # default
# Pagy::VARS[:cycle] = true # example


# Extras
# See https://ddnexus.github.io/pagy/extras


# Backend Extras

# Array extra: Paginate arrays efficiently, avoiding expensive array-wrapping and without overriding
# See https://ddnexus.github.io/pagy/extras/array
# require 'pagy/extras/array'

# Countless extra: Paginate without any count, saving one query per rendering
# See https://ddnexus.github.io/pagy/extras/countless
# require 'pagy/extras/countless'

# Elasticsearch Rails extra: Paginate `ElasticsearchRails::Results` objects
# See https://ddnexus.github.io/pagy/extras/elasticsearch_rails
# default :pagy_search method: change only if you use
# also the searchkick extra that defines the same
# VARS[:elasticsearch_rails_search_method] = :pagy_search
# require 'pagy/extras/elasticsearch_rails'

# Searchkick extra: Paginate `Searchkick::Results` objects
# See https://ddnexus.github.io/pagy/extras/searchkick
# default :pagy_search method: change only if you use
# also the elasticsearch_rails extra that defines the same
# VARS[:searchkick_search_method] = :pagy_search
# require 'pagy/extras/searchkick'

# Frontend Extras

# Bootstrap extra: Add nav, nav_js and combo_nav_js helpers and templates for Bootstrap pagination
# See https://ddnexus.github.io/pagy/extras/bootstrap
# require 'pagy/extras/bootstrap'

# Bulma extra: Add nav, nav_js and combo_nav_js helpers and templates for Bulma pagination
# See https://ddnexus.github.io/pagy/extras/bulma
# require 'pagy/extras/bulma'

# Foundation extra: Add nav, nav_js and combo_nav_js helpers and templates for Foundation pagination
# See https://ddnexus.github.io/pagy/extras/foundation
# require 'pagy/extras/foundation'

# Materialize extra: Add nav, nav_js and combo_nav_js helpers for Materialize pagination
# See https://ddnexus.github.io/pagy/extras/materialize
# require 'pagy/extras/materialize'

# Navs extra: Add nav_js and combo_nav_js javascript helpers
# Notice: the other frontend extras add their own framework-styled versions,
# so require this extra only if you need the unstyled version
# See https://ddnexus.github.io/pagy/extras/navs
# require 'pagy/extras/navs'

# Semantic extra: Add nav, nav_js and combo_nav_js helpers for Semantic UI pagination
# See https://ddnexus.github.io/pagy/extras/semantic
# require 'pagy/extras/semantic'

# UIkit extra: Add nav helper and templates for UIkit pagination
# See https://ddnexus.github.io/pagy/extras/uikit
# require 'pagy/extras/uikit'

# Multi size var used by the *_nav_js helpers
# See https://ddnexus.github.io/pagy/extras/navs#steps
# Pagy::VARS[:steps] = { 0 => [2,3,3,2], 540 => [3,5,5,3], 720 => [5,7,7,5] } # example


# Feature Extras

# Headers extra: http response headers (and other helpers) useful for API pagination
# See http://ddnexus.github.io/pagy/extras/headers
# require 'pagy/extras/headers'
# Pagy::VARS[:headers] = { page: 'Current-Page', items: 'Page-Items', count: 'Total-Count', pages: 'Total-Pages' } # default

# Support extra: Extra support for features like: incremental, infinite, auto-scroll pagination
# See https://ddnexus.github.io/pagy/extras/support
# require 'pagy/extras/support'

# Items extra: Allow the client to request a custom number of items per page with an optional selector UI
# See https://ddnexus.github.io/pagy/extras/items
# require 'pagy/extras/items'
# Pagy::VARS[:items_param] = :items # default
# Pagy::VARS[:max_items] = 100 # default
# set to false if you want to make :enable_items_extra an opt-in variable
# Pagy::VARS[:enable_items_extra] = false # default true

# Overflow extra: Allow for easy handling of overflowing pages
# See https://ddnexus.github.io/pagy/extras/overflow
# require 'pagy/extras/overflow'
# Pagy::VARS[:overflow] = :empty_page # default (other options: :last_page and :exception)

# Metadata extra: Provides the pagination metadata to Javascript frameworks like Vue.js, react.js, etc.
# See https://ddnexus.github.io/pagy/extras/metadata
# you must require the shared internal extra (BEFORE the metadata extra) ONLY if you need also the :sequels
# require 'pagy/extras/shared'
# require 'pagy/extras/metadata'
# For performance reason, you should explicitly set ONLY the metadata you use in the frontend
# Pagy::VARS[:metadata] = [:scaffold_url, :count, :page, :prev, :next, :last] # example

# Trim extra: Remove the page=1 param from links
# See https://ddnexus.github.io/pagy/extras/trim
# require 'pagy/extras/trim'
# after requiring it will trim by default
# set to false if you want to make :enable_trim_extra an opt-in variable
# Pagy::VARS[:enable_trim_extra] = false # default true


# Rails

# Rails: extras assets path required by the helpers that use javascript
# (pagy*_nav_js, pagy*_combo_nav_js, and pagy_items_selector_js)
# See https://ddnexus.github.io/pagy/extras#javascript
# Rails.application.config.assets.paths << Pagy.root.join('javascripts')


# I18n

# Pagy internal I18n: ~18x faster using ~10x less memory than the i18n gem
# See https://ddnexus.github.io/pagy/api/frontend#i18n
# Notice: No need to configure anything in this section if your app uses only "en"
# or if you use the i18n extra below
#
# Examples:
# load the "de" built-in locale:
# Pagy::I18n.load(locale: 'de')
#
# load the "de" locale defined in the custom file at :filepath:
# Pagy::I18n.load(locale: 'de', filepath: 'path/to/pagy-de.yml')
#
# load the "de", "en" and "es" built-in locales:
# (the first passed :locale will be used also as the default_locale)
# Pagy::I18n.load({locale: 'de'},
# {locale: 'en'},
# {locale: 'es'})
#
# load the "en" built-in locale, a custom "es" locale,
# and a totally custom locale complete with a custom :pluralize proc:
# (the first passed :locale will be used also as the default_locale)
# Pagy::I18n.load({locale: 'en'},
# {locale: 'es', filepath: 'path/to/pagy-es.yml'},
# {locale: 'xyz', # not built-in
# filepath: 'path/to/pagy-xyz.yml',
# pluralize: lambda{|count| ... } )


# I18n extra: uses the standard i18n gem which is ~18x slower using ~10x more memory
# than the default pagy internal i18n (see above)
# See https://ddnexus.github.io/pagy/extras/i18n
# require 'pagy/extras/i18n'

# Default i18n key
# Pagy::VARS[:i18n_key] = 'pagy.item_name' # default
2 changes: 1 addition & 1 deletion config/routes.rb
Expand Up @@ -5,7 +5,7 @@
skip_controllers :authorizations, :authorized_applications, :tokens, :token_info
end

devise_for :users
devise_for :users, controllers: { registrations: :registrations }

resources :keywords, only: :index

Expand Down
15 changes: 15 additions & 0 deletions db/migrate/20210624033123_create_keywords.rb
@@ -0,0 +1,15 @@
# frozen_string_literal: true

class CreateKeywords < ActiveRecord::Migration[6.1]
def change
create_table :keywords do |t|
t.string :name, null: false

t.references :user, index: true, null: false, foreign_key: true

t.timestamps
end

add_index :keywords, :name
end
end
@@ -0,0 +1,9 @@
class AddDiscardedAtToUsersAndKeywords < ActiveRecord::Migration[6.1]
def change
add_column :users, :discarded_at, :datetime
add_index :users, :discarded_at

add_column :keywords, :discarded_at, :datetime
add_index :keywords, :discarded_at
end
end
16 changes: 15 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions db/seeds.rb
Expand Up @@ -12,3 +12,9 @@
Doorkeeper::Application.create(name: "iOS client", redirect_uri: "", scopes: "")
Doorkeeper::Application.create(name: "Android client", redirect_uri: "", scopes: "")
end

if Rails.env.development?
user = User.where(email: 'admin@nimblehq.co').first_or_create(Fabricate.attributes_for(:admin, email: 'admin@nimblehq.co'))

Fabricate.times(100, :keyword, user: user)
end
6 changes: 6 additions & 0 deletions spec/fabricators/keyword_fabricator.rb
@@ -0,0 +1,6 @@
# frozen_string_literal: true

Fabricator(:keyword) do
name { FFaker::FreedomIpsum.word }
user { Fabricate(:user) }
end

0 comments on commit 5a3282a

Please sign in to comment.