diff --git a/Gemfile b/Gemfile index 8420c5f..21fa931 100644 --- a/Gemfile +++ b/Gemfile @@ -58,11 +58,11 @@ group :development, :test do gem 'dotenv-rails' # craate a .env file to set local environment variables gem 'factory_bot_rails' # model mocks with factory bot gem 'rspec-rails', '~> 3.8' # used testframework + gem 'faker', '~> 1.8' end group :test do gem 'database_cleaner', '~> 1.6' - gem 'faker', '~> 1.8' gem 'rails-controller-testing' gem 'shoulda-matchers', '4.0.0.rc1' gem 'simplecov', require: false diff --git a/README.md b/README.md index 0f9e22d..1ad2e3c 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ Download a GraphQL client like [GraphiQL](https://github.com/graphql/graphiql) o ## 🎁 What's included? ### 1. Database -The app uses a PostgreSQL database. It implements the connector with the gem `pg`. The app already includes a `User` and a `Account` model with basic setup. We see an `Account` as a company with it's users. We did **not** add multi-tenancy to this app. If you want to do it by yourself check out the [apartment](https://github.com/influitive/apartment) gem. +The app uses a PostgreSQL database. It implements the connector with the gem `pg`. The app already includes a `User` and a `Company` model with basic setup. We see an `Company` as a company with it's users. We did **not** add multi-tenancy to this app. If you want to do it by yourself check out the [apartment](https://github.com/influitive/apartment) gem. ### 2. Authentication @@ -162,7 +162,7 @@ We enable HTTP auth currently for all controllers. The `ApplicationController` c ### 13. Auto generated slugs -To provider more user friendly urls for your frontend we are using [friendly_id](https://github.com/norman/friendly_id) to auto generate slugs for models. We have already implemented it for the `Account` model. For more configuration see `config/initializers/friendly_id.rb`. +To provider more user friendly urls for your frontend we are using [friendly_id](https://github.com/norman/friendly_id) to auto generate slugs for models. We have already implemented it for the `Company` model. For more configuration see `config/initializers/friendly_id.rb`. To create a new slug field for a model add a field `slug`: @@ -174,15 +174,15 @@ $ bundle exec rake db:migrate Edit your model file as the following: ```ruby -class Account < ApplicationRecord +class Company < ApplicationRecord extend FriendlyId friendly_id :name, use: :slugged end ``` -Replace traditional `Account.find(params[:id])` with `Account.friendly.find(params[:id])` +Replace traditional `Company.find(params[:id])` with `Company.friendly.find(params[:id])` ```ruby - account = Account.friendly.find(params[:id]) + company = Company.friendly.find(params[:id]) ``` diff --git a/app/graphql/resolvers/account.rb b/app/graphql/resolvers/account.rb deleted file mode 100644 index 5813b87..0000000 --- a/app/graphql/resolvers/account.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module Resolvers - # Resolver to return a user - class Account < BaseResolver - type Types::AccountType, null: true - description 'Returns the account for the user.' - - def resolve - context[:current_user] ? context[:current_user].account : nil - end - end -end diff --git a/app/graphql/resolvers/company.rb b/app/graphql/resolvers/company.rb new file mode 100644 index 0000000..3c0fe80 --- /dev/null +++ b/app/graphql/resolvers/company.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Resolvers + # Resolver to return a user + class Company < BaseResolver + type Types::CompanyType, null: true + description 'Returns the company for the user.' + + def resolve + context[:current_user] ? context[:current_user].company : nil + end + end +end diff --git a/app/graphql/types/account_type.rb b/app/graphql/types/company_type.rb similarity index 73% rename from app/graphql/types/account_type.rb rename to app/graphql/types/company_type.rb index af55d44..2e5f716 100644 --- a/app/graphql/types/account_type.rb +++ b/app/graphql/types/company_type.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true module Types - # GraphQL type for an account - class AccountType < BaseModel + # GraphQL type for a company + class CompanyType < BaseModel field :name, String, null: false field :slug, String, null: true # field :users, [::Types::UserType], null: true diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb index 2f7828c..274adfe 100644 --- a/app/graphql/types/query_type.rb +++ b/app/graphql/types/query_type.rb @@ -8,11 +8,11 @@ class QueryType < BaseObject field :users, Types::UserType.connection_type, null: false def users(**_args) - ::User.accessible_by(current_ability).includes(:account) + ::User.accessible_by(current_ability).includes(:company) end field :user, resolver: Resolvers::User - field :account, resolver: Resolvers::Account + field :company, resolver: Resolvers::Company def current_ability Ability.new(context[:current_user]) diff --git a/app/graphql/types/user_type.rb b/app/graphql/types/user_type.rb index 4b42125..4b05eb3 100644 --- a/app/graphql/types/user_type.rb +++ b/app/graphql/types/user_type.rb @@ -7,6 +7,6 @@ class UserType < BaseModel field :first_name, String, null: false field :last_name, String, null: false field :email, String, null: true - field :account, Types::AccountType, null: false + field :company, Types::CompanyType, null: false end end diff --git a/app/models/ability.rb b/app/models/ability.rb index b63f319..443fffd 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -15,9 +15,9 @@ def initialize(user) can :access, :rails_admin # grant access to rails_admin can :manage, :all # admins can manage all objects elsif user.admin? - can :crud, User, account_id: user.account_id + can :crud, User, company_id: user.company_id else - can :read, User, account_id: user.account_id + can :read, User, company_id: user.company_id end # See the wiki for details: diff --git a/app/models/account.rb b/app/models/company.rb similarity index 91% rename from app/models/account.rb rename to app/models/company.rb index b14c450..dee3a62 100644 --- a/app/models/account.rb +++ b/app/models/company.rb @@ -2,7 +2,7 @@ # == Schema Information # -# Table name: accounts +# Table name: companies # # id :uuid not null, primary key # name :string @@ -13,9 +13,9 @@ # # Indexes # -# index_accounts_on_slug (slug) UNIQUE +# index_companies_on_slug (slug) UNIQUE # -class Account < ApplicationRecord +class Company < ApplicationRecord extend FriendlyId # - EXTENSIONS diff --git a/app/models/user.rb b/app/models/user.rb index 991e1d0..126c4c6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -28,7 +28,7 @@ # unlock_token :string # created_at :datetime not null # updated_at :datetime not null -# account_id :uuid +# company_id :uuid # # Indexes # @@ -60,11 +60,11 @@ class User < ApplicationRecord validates :last_name, length: { maximum: 255 } # - RELATIONS - belongs_to :account, counter_cache: true + belongs_to :company, counter_cache: true # - CALLBACKS after_initialize :setup_new_user, if: :new_record? - before_validation :setup_account + before_validation :setup_company # return first and lastname def name @@ -80,8 +80,8 @@ def status_color private - def setup_account - self.account = Account.create!(name: 'My company') if account.nil? + def setup_company + self.company = Company.create!(name: 'My company') if company.nil? end def setup_new_user @@ -121,7 +121,7 @@ def setup_new_user field :email field :role field :last_sign_in_at - field :account + field :company end edit do @@ -131,7 +131,7 @@ def setup_new_user field :password field :password_confirmation field :role - field :account + field :company end show do @@ -141,7 +141,7 @@ def setup_new_user field :email field :role field :last_sign_in_at - field :account + field :company end end # rubocop:enable Metrics/BlockLength diff --git a/config/locales/activerecord/de.yml b/config/locales/activerecord/de.yml index f34c32d..e85c085 100644 --- a/config/locales/activerecord/de.yml +++ b/config/locales/activerecord/de.yml @@ -3,7 +3,7 @@ de: slug: Pfad activerecord: attributes: - account: + company: name: Name des Unternehmens users_count: Anzahl Mitarbeiter user: @@ -37,6 +37,6 @@ de: user: one: Benutzer other: Benutzer - account: - one: Konto - other: Konten + company: + one: Unternehmen + other: Unternehmen diff --git a/config/locales/activerecord/en.yml b/config/locales/activerecord/en.yml index 53e84a4..52b0e7a 100644 --- a/config/locales/activerecord/en.yml +++ b/config/locales/activerecord/en.yml @@ -3,7 +3,7 @@ en: slug: Slug activerecord: attributes: - account: + company: name: Name of company users_count: Number of employees user: @@ -37,6 +37,6 @@ en: user: one: User other: Users - account: - one: Account - other: Accounts + company: + one: Company + other: Companies diff --git a/db/migrate/20190209163712_devise_create_users.rb b/db/migrate/20190209163712_devise_create_users.rb index 445098d..8450519 100644 --- a/db/migrate/20190209163712_devise_create_users.rb +++ b/db/migrate/20190209163712_devise_create_users.rb @@ -45,7 +45,7 @@ def change t.timestamps null: false - t.uuid :account_id + t.uuid :company_id end add_index :users, :email, unique: true diff --git a/db/migrate/20200912120337_create_accounts.rb b/db/migrate/20200912120337_create_companies.rb similarity index 50% rename from db/migrate/20200912120337_create_accounts.rb rename to db/migrate/20200912120337_create_companies.rb index ea3f66f..96d6d03 100644 --- a/db/migrate/20200912120337_create_accounts.rb +++ b/db/migrate/20200912120337_create_companies.rb @@ -1,6 +1,6 @@ -class CreateAccounts < ActiveRecord::Migration[6.0] +class CreateCompanies < ActiveRecord::Migration[6.0] def change - create_table :accounts, id: :uuid do |t| + create_table :companies, id: :uuid do |t| t.string :name t.integer :users_count t.timestamps diff --git a/db/migrate/20200912153138_add_slug_to_accounts.rb b/db/migrate/20200912153138_add_slug_to_accounts.rb deleted file mode 100644 index 666a8c7..0000000 --- a/db/migrate/20200912153138_add_slug_to_accounts.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddSlugToAccounts < ActiveRecord::Migration[6.0] - def change - add_column :accounts, :slug, :string - add_index :accounts, :slug, unique: true - end -end diff --git a/db/migrate/20200912153138_add_slug_to_companies.rb b/db/migrate/20200912153138_add_slug_to_companies.rb new file mode 100644 index 0000000..f753515 --- /dev/null +++ b/db/migrate/20200912153138_add_slug_to_companies.rb @@ -0,0 +1,6 @@ +class AddSlugToCompanies < ActiveRecord::Migration[6.0] + def change + add_column :companies, :slug, :string + add_index :companies, :slug, unique: true + end +end diff --git a/db/migrate/20200912153858_create_friendly_id_slugs.rb b/db/migrate/20200912153858_create_friendly_id_slugs.rb index 135e5ce..ac9606a 100644 --- a/db/migrate/20200912153858_create_friendly_id_slugs.rb +++ b/db/migrate/20200912153858_create_friendly_id_slugs.rb @@ -12,6 +12,6 @@ def change add_index :friendly_id_slugs, [:slug, :sluggable_type, :scope], :unique => true add_index :friendly_id_slugs, :sluggable_type - Account.all.each(&:save) + Company.all.each(&:save) end end diff --git a/db/schema.rb b/db/schema.rb index fdcfb3b..bf894fc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -16,15 +16,6 @@ enable_extension "pgcrypto" enable_extension "plpgsql" - create_table "accounts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| - t.string "name" - t.integer "users_count" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false - t.string "slug" - t.index ["slug"], name: "index_accounts_on_slug", unique: true - end - create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false t.string "record_type", null: false @@ -46,6 +37,15 @@ t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true end + create_table "companies", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.string "name" + t.integer "users_count" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "slug" + t.index ["slug"], name: "index_companies_on_slug", unique: true + end + create_table "friendly_id_slugs", force: :cascade do |t| t.string "slug", null: false t.integer "sluggable_id", null: false @@ -82,7 +82,7 @@ t.integer "role", default: 0, null: false t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false - t.uuid "account_id" + t.uuid "company_id" t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true t.index ["email"], name: "index_users_on_email", unique: true t.index ["refresh_token"], name: "index_users_on_refresh_token", unique: true diff --git a/db/seeds.rb b/db/seeds.rb index 247efa3..08af8d1 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -9,4 +9,34 @@ if user Rails.logger.info "Login with #{ENV['ADMIN_EMAIL']} and #{ENV['ADMIN_PASSWORD']}" -end \ No newline at end of file +end + +# Create a admin user +admin = User.create( + email: Faker::Internet.email, + password: ENV['ADMIN_PASSWORD'], + password_confirmation: ENV['ADMIN_PASSWORD'], + first_name: Faker::Name.first_name, + last_name: Faker::Name.last_name, + role: 'admin' +) + +User.create( + email: Faker::Internet.email, + password: ENV['ADMIN_PASSWORD'], + password_confirmation: ENV['ADMIN_PASSWORD'], + first_name: Faker::Name.first_name, + last_name: Faker::Name.last_name, + role: 'user', + company_id: admin.company_id +) + +User.create( + email: Faker::Internet.email, + password: ENV['ADMIN_PASSWORD'], + password_confirmation: ENV['ADMIN_PASSWORD'], + first_name: Faker::Name.first_name, + last_name: Faker::Name.last_name, + role: 'user', + company_id: admin.company_id +) diff --git a/spec/factories/accounts.rb b/spec/factories/companies.rb similarity index 79% rename from spec/factories/accounts.rb rename to spec/factories/companies.rb index a3f3a44..65d7262 100644 --- a/spec/factories/accounts.rb +++ b/spec/factories/companies.rb @@ -2,7 +2,7 @@ # == Schema Information # -# Table name: accounts +# Table name: companies # # id :uuid not null, primary key # name :string @@ -13,10 +13,10 @@ # # Indexes # -# index_accounts_on_slug (slug) UNIQUE +# index_companies_on_slug (slug) UNIQUE # FactoryBot.define do - factory :account do + factory :company do name { 'My Company' } end end diff --git a/spec/factories/users.rb b/spec/factories/users.rb index e4d0994..1292726 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -28,7 +28,7 @@ # unlock_token :string # created_at :datetime not null # updated_at :datetime not null -# account_id :uuid +# company_id :uuid # # Indexes # @@ -45,7 +45,7 @@ email { Faker::Internet.email } password { 'password' } password_confirmation { 'password' } - association :account + association :company trait :user do role { :user } diff --git a/spec/graphql/resolvers/account_spec.rb b/spec/graphql/resolvers/company_spec.rb similarity index 73% rename from spec/graphql/resolvers/account_spec.rb rename to spec/graphql/resolvers/company_spec.rb index 936a558..438e8d3 100644 --- a/spec/graphql/resolvers/account_spec.rb +++ b/spec/graphql/resolvers/company_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe Resolvers::Account, type: :request do +RSpec.describe Resolvers::Company, type: :request do subject(:graphql!) { result } let(:result) do @@ -20,7 +20,7 @@ let(:query_string) do <<-GRAPHQL query { - account { + company { id name } @@ -28,7 +28,7 @@ GRAPHQL end - describe 'account' do + describe 'company' do context 'when there\'s no current user' do let(:context) do { @@ -38,7 +38,7 @@ it 'returns nil' do graphql! - expect(result['data']['account']).to eq(nil) + expect(result['data']['company']).to eq(nil) end end @@ -53,10 +53,10 @@ } end - it 'returns account of user' do + it 'returns company of user' do graphql! - account_id = result['data']['account']['id'] - expect(account_id).to eq(user.account.id) + company_id = result['data']['company']['id'] + expect(company_id).to eq(user.company.id) end end end diff --git a/spec/graphql/resolvers/user_spec.rb b/spec/graphql/resolvers/user_spec.rb index 9f2ebb3..783e9de 100644 --- a/spec/graphql/resolvers/user_spec.rb +++ b/spec/graphql/resolvers/user_spec.rb @@ -5,12 +5,12 @@ RSpec.describe Resolvers::User, type: :request do subject(:graphql!) { result } - let!(:account) do - create(:account) + let!(:company) do + create(:company) end let!(:admin) do - create(:user, :admin, account_id: account.id) + create(:user, :admin, company_id: company.id) end let(:result) do @@ -39,9 +39,9 @@ end describe 'user' do - context 'when user is not member of this account' do + context 'when user is not member of this company' do let(:user) do - create(:user, account: create(:account)) + create(:user, company: create(:company)) end let(:variables) do @@ -54,9 +54,9 @@ end end - context 'when user is admin of this account' do + context 'when user is admin of this company' do let(:user) do - create(:user, account_id: account.id) + create(:user, company_id: company.id) end let(:variables) do @@ -70,13 +70,13 @@ end end - context 'when user is member of this account' do + context 'when user is member of this company' do let(:user) do - create(:user, account_id: account.id) + create(:user, company_id: company.id) end let(:user2) do - create(:user, account_id: account.id) + create(:user, company_id: company.id) end let(:context) do diff --git a/spec/graphql/types/query_type_users_spec.rb b/spec/graphql/types/query_type_users_spec.rb index e0fbdfb..d6c6492 100644 --- a/spec/graphql/types/query_type_users_spec.rb +++ b/spec/graphql/types/query_type_users_spec.rb @@ -5,12 +5,12 @@ RSpec.describe Types::QueryType, type: :request do subject(:graphql!) { result } - let!(:account) do - create(:account) + let!(:company) do + create(:company) end let!(:admin) do - create(:user, :admin, account_id: account.id) + create(:user, :admin, company_id: company.id) end let(:result) do @@ -67,7 +67,7 @@ let(:context) { { current_user: user } } - before { create_list(:user, 3, account: user.account) } + before { create_list(:user, 3, company: user.company) } it 'returns user in edges.' do graphql! diff --git a/spec/models/account_spec.rb b/spec/models/company_spec.rb similarity index 76% rename from spec/models/account_spec.rb rename to spec/models/company_spec.rb index ce62a11..5e77ce8 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/company_spec.rb @@ -2,7 +2,7 @@ # == Schema Information # -# Table name: accounts +# Table name: companies # # id :uuid not null, primary key # name :string @@ -13,13 +13,13 @@ # # Indexes # -# index_accounts_on_slug (slug) UNIQUE +# index_companies_on_slug (slug) UNIQUE # require 'rails_helper' -RSpec.describe Account, type: :model do +RSpec.describe Company, type: :model do it 'has a valid factory' do - expect(create(:account)).to be_valid + expect(create(:company)).to be_valid end # Validations diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 4d93215..936cccf 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -28,7 +28,7 @@ # unlock_token :string # created_at :datetime not null # updated_at :datetime not null -# account_id :uuid +# company_id :uuid # # Indexes #