diff --git a/.rubocop.yml b/.rubocop.yml index 89f3b6bdbd..d31d7b05e9 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -56,4 +56,8 @@ Style/HashEachMethods: Style/HashTransformKeys: Enabled: false Style/HashTransformValues: - Enabled: false \ No newline at end of file + Enabled: false +Layout/EndOfLine: + Enabled: false +Metrics/PerceivedComplexity: + Enabled: false diff --git a/Gemfile b/Gemfile index 67b156b339..0a0c328dd3 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } -ruby '2.7.0' +ruby '2.7.3' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 5.2.4' @@ -45,9 +45,18 @@ group :development, :test do end group :test do - gem 'rspec' + gem 'rspec-rails' + gem 'rswag-specs' + gem 'shoulda', '~> 4.0' + # Adds support for Capybara system testing and selenium driver + gem 'capybara', '>= 3.26' + gem 'selenium-webdriver' + gem 'webdrivers' end +gem 'jwt' +gem 'rswag' + group :development do # Access an interactive console on exception pages or by calling 'console' anywhere in the code. gem 'listen', '>= 3.0.5', '< 3.2' diff --git a/Gemfile.lock b/Gemfile.lock index b67d4b3306..c21bdda360 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,55 +1,66 @@ GEM remote: https://rubygems.org/ specs: - actioncable (5.2.4.1) - actionpack (= 5.2.4.1) + actioncable (5.2.6) + actionpack (= 5.2.6) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailer (5.2.4.1) - actionpack (= 5.2.4.1) - actionview (= 5.2.4.1) - activejob (= 5.2.4.1) + actionmailer (5.2.6) + actionpack (= 5.2.6) + actionview (= 5.2.6) + activejob (= 5.2.6) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.2.4.1) - actionview (= 5.2.4.1) - activesupport (= 5.2.4.1) + actionpack (5.2.6) + actionview (= 5.2.6) + activesupport (= 5.2.6) rack (~> 2.0, >= 2.0.8) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.2.4.1) - activesupport (= 5.2.4.1) + actionview (5.2.6) + activesupport (= 5.2.6) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.3) - activejob (5.2.4.1) - activesupport (= 5.2.4.1) + activejob (5.2.6) + activesupport (= 5.2.6) globalid (>= 0.3.6) - activemodel (5.2.4.1) - activesupport (= 5.2.4.1) - activerecord (5.2.4.1) - activemodel (= 5.2.4.1) - activesupport (= 5.2.4.1) + activemodel (5.2.6) + activesupport (= 5.2.6) + activerecord (5.2.6) + activemodel (= 5.2.6) + activesupport (= 5.2.6) arel (>= 9.0) - activestorage (5.2.4.1) - actionpack (= 5.2.4.1) - activerecord (= 5.2.4.1) - marcel (~> 0.3.1) - activesupport (5.2.4.1) + activestorage (5.2.6) + actionpack (= 5.2.6) + activerecord (= 5.2.6) + marcel (~> 1.0.0) + activesupport (5.2.6) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) arel (9.0.0) - ast (2.4.0) - bcrypt (3.1.13) + ast (2.4.2) + bcrypt (3.1.16) bindex (0.8.1) - bootsnap (1.4.6) + bootsnap (1.7.5) msgpack (~> 1.0) builder (3.2.4) - byebug (11.1.1) + byebug (11.1.3) + capybara (3.35.3) + addressable + mini_mime (>= 0.1.3) + nokogiri (~> 1.8) + rack (>= 1.6.0) + rack-test (>= 0.6.3) + regexp_parser (>= 1.5, < 3.0) + xpath (~> 3.2) + childprocess (3.0.0) coffee-rails (4.2.2) coffee-script (>= 2.2.0) railties (>= 4.0.0) @@ -57,117 +68,133 @@ GEM coffee-script-source execjs coffee-script-source (1.12.2) - concurrent-ruby (1.1.6) + concurrent-ruby (1.1.9) crass (1.0.6) - devise (4.7.1) + devise (4.8.0) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) responders warden (~> 1.2.3) - diff-lcs (1.3) - erubi (1.9.0) - execjs (2.7.0) - ffi (1.12.2) - ffi (1.12.2-x64-mingw32) + diff-lcs (1.4.4) + erubi (1.10.0) + execjs (2.8.1) + ffi (1.15.3-x64-mingw32) globalid (0.4.2) activesupport (>= 4.2.0) - i18n (1.8.2) + i18n (1.8.10) concurrent-ruby (~> 1.0) - jaro_winkler (1.5.4) - jbuilder (2.10.0) + jbuilder (2.11.2) activesupport (>= 5.0.0) + json-schema (2.8.1) + addressable (>= 2.4) + jwt (2.3.0) listen (3.1.5) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) ruby_dep (~> 1.2) - loofah (2.4.0) + loofah (2.10.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) - marcel (0.3.3) - mimemagic (~> 0.3.2) - method_source (0.9.2) - mimemagic (0.3.4) - mini_mime (1.0.2) - mini_portile2 (2.5.0) - minitest (5.14.0) - msgpack (1.3.3) - msgpack (1.3.3-x64-mingw32) - nio4r (2.5.2) - nokogiri (1.11.1) - mini_portile2 (~> 2.5.0) - racc (~> 1.4) - nokogiri (1.11.1-x64-mingw32) + marcel (1.0.1) + method_source (1.0.0) + mini_mime (1.1.0) + minitest (5.14.4) + msgpack (1.4.2) + nio4r (2.5.7) + nokogiri (1.11.7-x64-mingw32) racc (~> 1.4) orm_adapter (0.5.0) - parallel (1.19.1) - parser (2.7.0.4) - ast (~> 2.4.0) - pg (1.2.2) - pg (1.2.2-x64-mingw32) + parallel (1.20.1) + parser (3.0.1.1) + ast (~> 2.4.1) + pg (1.2.3-x64-mingw32) + public_suffix (4.0.6) puma (3.12.6) racc (1.5.2) rack (2.2.3) rack-test (1.1.0) rack (>= 1.0, < 3) - rails (5.2.4.1) - actioncable (= 5.2.4.1) - actionmailer (= 5.2.4.1) - actionpack (= 5.2.4.1) - actionview (= 5.2.4.1) - activejob (= 5.2.4.1) - activemodel (= 5.2.4.1) - activerecord (= 5.2.4.1) - activestorage (= 5.2.4.1) - activesupport (= 5.2.4.1) + rails (5.2.6) + actioncable (= 5.2.6) + actionmailer (= 5.2.6) + actionpack (= 5.2.6) + actionview (= 5.2.6) + activejob (= 5.2.6) + activemodel (= 5.2.6) + activerecord (= 5.2.6) + activestorage (= 5.2.6) + activesupport (= 5.2.6) bundler (>= 1.3.0) - railties (= 5.2.4.1) + railties (= 5.2.6) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) rails-html-sanitizer (1.3.0) loofah (~> 2.3) - railties (5.2.4.1) - actionpack (= 5.2.4.1) - activesupport (= 5.2.4.1) + railties (5.2.6) + actionpack (= 5.2.6) + activesupport (= 5.2.6) method_source rake (>= 0.8.7) thor (>= 0.19.0, < 2.0) rainbow (3.0.0) - rake (13.0.1) - rb-fsevent (0.10.3) + rake (13.0.3) + rb-fsevent (0.11.0) rb-inotify (0.10.1) ffi (~> 1.0) - responders (3.0.0) + regexp_parser (2.1.1) + responders (3.0.1) actionpack (>= 5.0) railties (>= 5.0) - rexml (3.2.4) - rspec (3.9.0) - rspec-core (~> 3.9.0) - rspec-expectations (~> 3.9.0) - rspec-mocks (~> 3.9.0) - rspec-core (3.9.1) - rspec-support (~> 3.9.1) - rspec-expectations (3.9.1) + rexml (3.2.5) + rspec-core (3.10.1) + rspec-support (~> 3.10.0) + rspec-expectations (3.10.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.9.0) - rspec-mocks (3.9.1) + rspec-support (~> 3.10.0) + rspec-mocks (3.10.2) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.9.0) - rspec-support (3.9.2) - rubocop (0.80.1) - jaro_winkler (~> 1.5.1) + rspec-support (~> 3.10.0) + rspec-rails (5.0.1) + actionpack (>= 5.2) + activesupport (>= 5.2) + railties (>= 5.2) + rspec-core (~> 3.10) + rspec-expectations (~> 3.10) + rspec-mocks (~> 3.10) + rspec-support (~> 3.10) + rspec-support (3.10.2) + rswag (2.4.0) + rswag-api (= 2.4.0) + rswag-specs (= 2.4.0) + rswag-ui (= 2.4.0) + rswag-api (2.4.0) + railties (>= 3.1, < 7.0) + rswag-specs (2.4.0) + activesupport (>= 3.1, < 7.0) + json-schema (~> 2.2) + railties (>= 3.1, < 7.0) + rswag-ui (2.4.0) + actionpack (>= 3.1, < 7.0) + railties (>= 3.1, < 7.0) + rubocop (1.17.0) parallel (~> 1.10) - parser (>= 2.7.0.1) + parser (>= 3.0.0.0) rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) rexml + rubocop-ast (>= 1.7.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 1.7) - ruby-progressbar (1.10.1) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.7.0) + parser (>= 3.0.1.1) + ruby-progressbar (1.11.0) ruby_dep (1.5.0) + rubyzip (2.3.0) sass (3.7.4) sass-listen (~> 4.0.0) sass-listen (4.0.0) @@ -179,67 +206,90 @@ GEM sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) - spring (2.1.0) + selenium-webdriver (3.142.7) + childprocess (>= 0.5, < 4.0) + rubyzip (>= 1.2.2) + shoulda (4.0.0) + shoulda-context (~> 2.0) + shoulda-matchers (~> 4.0) + shoulda-context (2.0.0) + shoulda-matchers (4.5.1) + activesupport (>= 4.2.0) + spring (2.1.1) spring-watcher-listen (2.0.1) listen (>= 2.7, < 4.0) spring (>= 1.2, < 3.0) sprockets (3.7.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.2.1) + sprockets-rails (3.2.2) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) - thor (1.0.1) + thor (1.1.0) thread_safe (0.3.6) tilt (2.0.10) turbolinks (5.2.1) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) - tzinfo (1.2.6) + tzinfo (1.2.9) thread_safe (~> 0.1) - tzinfo-data (1.2020.1) + tzinfo-data (1.2021.1) tzinfo (>= 1.0.0) uglifier (4.2.0) execjs (>= 0.3.0, < 3) - unicode-display_width (1.6.1) - warden (1.2.8) - rack (>= 2.0.6) + unicode-display_width (2.0.0) + warden (1.2.9) + rack (>= 2.0.9) + wdm (0.1.1) web-console (3.7.0) actionview (>= 5.0) activemodel (>= 5.0) bindex (>= 0.4.0) railties (>= 5.0) - websocket-driver (0.7.1) + webdrivers (4.6.0) + nokogiri (~> 1.6) + rubyzip (>= 1.3.0) + selenium-webdriver (>= 3.0, < 4.0) + websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) + xpath (3.2.0) + nokogiri (~> 1.8) PLATFORMS - ruby x64-mingw32 DEPENDENCIES bootsnap (>= 1.1.0) byebug + capybara (>= 3.26) coffee-rails (~> 4.2) devise jbuilder (~> 2.5) + jwt listen (>= 3.0.5, < 3.2) pg (>= 0.18, < 2.0) puma (~> 3.12) rails (~> 5.2.4) - rspec + rspec-rails + rswag + rswag-specs rubocop sass-rails (~> 5.0) + selenium-webdriver + shoulda (~> 4.0) spring spring-watcher-listen (~> 2.0.0) turbolinks (~> 5) tzinfo-data uglifier (>= 1.3.0) + wdm (>= 0.1.0) web-console (>= 3.3.0) + webdrivers RUBY VERSION - ruby 2.7.0p0 + ruby 2.7.3p183 BUNDLED WITH - 2.1.2 + 2.2.19 diff --git a/Procfile b/Procfile new file mode 100644 index 0000000000..cff361aa9a --- /dev/null +++ b/Procfile @@ -0,0 +1,2 @@ +web: rails server +release: bundle exec rails db:migrate \ No newline at end of file diff --git a/README.md b/README.md index e2ff61f120..fa14cfd639 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,17 @@ # Scaffold for social media app with Ruby on Rails -> This repo includes intial code for social media app with basic styling. Its purpose is to be a starting point for Microverse students. +> This repo includes intial code for social media app with basic styling. Its purpose is to be a starting point for Microverse students. Add frienship model. Deploy Application to heroku. + + ## Built With -- Ruby v2.7.0 -- Ruby on Rails v5.2.4 +- Ruby v2.7.3 +- Ruby on Rails v6.1.3.2 ## Live Demo -TBA - +[Live Demo Link](https://stay-in-touch-vikita.herokuapp.com/) ## Getting Started @@ -18,24 +19,23 @@ To get a local copy up and running follow these simple example steps. ### Prerequisites -Ruby: 2.6.3 -Rails: 5.2.3 +Ruby: 2.7.3 +Rails: 6.1.3.2 Postgres: >=9.5 -### Setup - -Instal gems with: - -``` -bundle install -``` - -Setup database with: +## Getting Started -``` - rails db:create - rails db:migrate -``` +- Ensure you have rails installed by running 'rails -v'. Otherwise run 'gem install rails' +- Click on the `Code` green button +- By the right end of the read-only input containing the repository link click the clipboard icon to copy the link +- In your local PC, open your terminal in the folder you would like to clone the repository into +- Clone the repository with the command: `git clone (copied link)`; like so: `git clone https://github.com/vikitaotiz/ror-social-scaffold.git` +- After the clone, type in the command `cd ror-social-scaffold` to access the app directory on the terminal +- Then run 'bundle install' to install all the required dependencies +- Then run 'npm install' to avoid this error 'Webpacker::Manifest::MissingEntryError in posts#index' +- Run 'rails db:create db:migrate' +- Run 'rails server' to spin up a development server +- Once the server is up, open this link 'http://127.0.0.1:3000' on your browser ### Github Actions @@ -46,32 +46,19 @@ To make sure the linters' checks using Github Actions work properly, you should 3. Start working on your milestone as usual. 4. Open a PR from the `feature/branch` when your work is done. - -### Usage - -Start server with: - -``` - rails server -``` - -Open `http://localhost:3000/` in your browser. - ### Run tests -``` - rpsec --format documentation -``` - -> Tests will be added by Microverse students. There are no tests for initial features in order to make sure that students write all tests from scratch. - -### Deployment - -TBA +- Navigate into the app directory, `cd ror-social-scaffold` +- Then run `rails db:migrate db:test:prepare` +- Then run `rspec --format doc`. This will display detailed information about models and test results. ## Authors -TBA +:bust_in_silhouette: **Victor Otieno** + +- GitHub: [@githubhandle](https://github.com/vikitaotiz) +- Twitter: [@twitterhandle](https://twitter.com/victoro29641869) +- LinkedIn: [LinkedIn](https://www.linkedin.com/in/victor-otieno-oluoch/) ## 🤝 Contributing @@ -85,9 +72,4 @@ Give a ⭐️ if you like this project! ## Acknowledgments -TBA - -## 📝 License - -TBA - +- Microverse Team diff --git a/app/assets/javascripts/api.coffee b/app/assets/javascripts/api.coffee new file mode 100644 index 0000000000..24f83d18bb --- /dev/null +++ b/app/assets/javascripts/api.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/api/v1/auth.coffee b/app/assets/javascripts/api/v1/auth.coffee new file mode 100644 index 0000000000..24f83d18bb --- /dev/null +++ b/app/assets/javascripts/api/v1/auth.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/api/v1/base.coffee b/app/assets/javascripts/api/v1/base.coffee new file mode 100644 index 0000000000..24f83d18bb --- /dev/null +++ b/app/assets/javascripts/api/v1/base.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/api/v1/comments.coffee b/app/assets/javascripts/api/v1/comments.coffee new file mode 100644 index 0000000000..24f83d18bb --- /dev/null +++ b/app/assets/javascripts/api/v1/comments.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/api/v1/posts.coffee b/app/assets/javascripts/api/v1/posts.coffee new file mode 100644 index 0000000000..24f83d18bb --- /dev/null +++ b/app/assets/javascripts/api/v1/posts.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/api/v1/register.coffee b/app/assets/javascripts/api/v1/register.coffee new file mode 100644 index 0000000000..24f83d18bb --- /dev/null +++ b/app/assets/javascripts/api/v1/register.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/api/v1/registration.coffee b/app/assets/javascripts/api/v1/registration.coffee new file mode 100644 index 0000000000..24f83d18bb --- /dev/null +++ b/app/assets/javascripts/api/v1/registration.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/friendships.coffee b/app/assets/javascripts/friendships.coffee new file mode 100644 index 0000000000..24f83d18bb --- /dev/null +++ b/app/assets/javascripts/friendships.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/api.scss b/app/assets/stylesheets/api.scss new file mode 100644 index 0000000000..5836003d41 --- /dev/null +++ b/app/assets/stylesheets/api.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the api controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/api/v1/auth.scss b/app/assets/stylesheets/api/v1/auth.scss new file mode 100644 index 0000000000..6366512a7a --- /dev/null +++ b/app/assets/stylesheets/api/v1/auth.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the api/v1/auth controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/api/v1/base.scss b/app/assets/stylesheets/api/v1/base.scss new file mode 100644 index 0000000000..42526066f3 --- /dev/null +++ b/app/assets/stylesheets/api/v1/base.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the api/v1/base controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/api/v1/comments.scss b/app/assets/stylesheets/api/v1/comments.scss new file mode 100644 index 0000000000..b838a428a5 --- /dev/null +++ b/app/assets/stylesheets/api/v1/comments.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the api/v1/comments controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/api/v1/posts.scss b/app/assets/stylesheets/api/v1/posts.scss new file mode 100644 index 0000000000..597ae1e37e --- /dev/null +++ b/app/assets/stylesheets/api/v1/posts.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the api/v1/posts controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/api/v1/register.scss b/app/assets/stylesheets/api/v1/register.scss new file mode 100644 index 0000000000..ad5966081c --- /dev/null +++ b/app/assets/stylesheets/api/v1/register.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the api/v1/register controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/api/v1/registration.scss b/app/assets/stylesheets/api/v1/registration.scss new file mode 100644 index 0000000000..fb00be635c --- /dev/null +++ b/app/assets/stylesheets/api/v1/registration.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the api/v1/registration controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/friendships.scss b/app/assets/stylesheets/friendships.scss new file mode 100644 index 0000000000..9bda05bc68 --- /dev/null +++ b/app/assets/stylesheets/friendships.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Friendships controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/api/v1/auth_controller.rb b/app/controllers/api/v1/auth_controller.rb new file mode 100644 index 0000000000..bb5c59b607 --- /dev/null +++ b/app/controllers/api/v1/auth_controller.rb @@ -0,0 +1,13 @@ +class Api::V1::AuthController < Api::V1::ApiController + skip_before_action :authenticate_user! + protect_from_forgery with: :exception + + def create + user = User.find_by(email: params[:email]) + if user.valid_password? params[:password] + render json: { token: JsonWebToken.encode(sub: user.id), success: ['User logged in successfully.'] } + else + render json: { errors: ['Invalid email or password'] } + end + end +end diff --git a/app/controllers/api/v1/comments_controller.rb b/app/controllers/api/v1/comments_controller.rb new file mode 100644 index 0000000000..4ffff4f50c --- /dev/null +++ b/app/controllers/api/v1/comments_controller.rb @@ -0,0 +1,8 @@ +class Api::V1::CommentsController < ApplicationController + def create + @post = Post.find(params[:id]) + @comment = @post.comments.create(user: current_user, content: params[:content]) + + render json: { data: @comment }, status: :ok if @comment.save + end +end diff --git a/app/controllers/api/v1/posts_controller.rb b/app/controllers/api/v1/posts_controller.rb new file mode 100644 index 0000000000..eaf2ec78f2 --- /dev/null +++ b/app/controllers/api/v1/posts_controller.rb @@ -0,0 +1,11 @@ +class Api::V1::PostsController < ApplicationController + def index + posts = Post.all + render json: { data: posts }, status: :ok + end + + def show + post = Post.find(params[:id]) + render json: { data: post.comments.all }, status: :ok + end +end diff --git a/app/controllers/api/v1/register_controller.rb b/app/controllers/api/v1/register_controller.rb new file mode 100644 index 0000000000..7670af9b09 --- /dev/null +++ b/app/controllers/api/v1/register_controller.rb @@ -0,0 +1,16 @@ +class Api::V1::RegisterController < ApplicationController + protect_from_forgery with: :null_session + + def create + @user = User.create(name: params[:name], + email: params[:email], + password: params[:password], + password_confirmation: params[:password_confirmation]) + + if @user.save + render json: { token: JsonWebToken.encode(sub: @user.id), success: ['User added successfully.'] } + else + render json: { errors: ['Registration failed'] } + end + end +end diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb new file mode 100644 index 0000000000..b4615fecff --- /dev/null +++ b/app/controllers/api_controller.rb @@ -0,0 +1,10 @@ +class ApiController < ApplicationController + before_action :set_default_format + before_action :authenticate_user! + + private + + def set_default_format + request.format = :json + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b5056310d4..f71129bde9 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,5 +1,6 @@ class ApplicationController < ActionController::Base protect_from_forgery with: :exception + skip_before_action :verify_authenticity_token before_action :configure_permitted_parameters, if: :devise_controller? diff --git a/app/controllers/friendships_controller.rb b/app/controllers/friendships_controller.rb new file mode 100644 index 0000000000..55d496baca --- /dev/null +++ b/app/controllers/friendships_controller.rb @@ -0,0 +1,11 @@ +class FriendshipsController < ApplicationController + def create + user = User.find(params[:friend_id]) + @add_friend = current_user.friendships.new(friend_id: user.id, status: false) + if @add_friend.save + redirect_to users_path, notice: 'Friend request sent.' + else + redirect_to users_path, alert: 'You friend request was not sent.' + end + end +end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 0062aebe55..7efbf656d0 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -20,7 +20,19 @@ def create private def timeline_posts - @timeline_posts ||= Post.all.ordered_by_most_recent.includes(:user) + ids = [] + # returns ids of accepted friends of currently logged in user + current_user.friendships.each { |f| ids << f.friend_id if f.status == true } + @timeline_posts = [] + # add id of currently logged in user to ids array + ids << current_user.id + # returns posts of currently logged in user and their friends + i = 0 + while i < ids.length + @timeline_posts += Post.where('user_id = ?', ids[i]) + i += 1 + end + @timeline_posts.reverse! end def post_params diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index b0350d70e4..7a319f872f 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -8,5 +8,41 @@ def index def show @user = User.find(params[:id]) @posts = @user.posts.ordered_by_most_recent + @friends = Friendship.where('friend_id = ? and status = ?', current_user.id, true) + @friends.all.map(&:user_id) + @all_friends = [] + @friends.each { |u| @all_friends << User.find(u.user_id) } + end + + def confirm + user = User.find(params[:friend_id]) + friend = Friendship.where('friend_id = ? and user_id = ?', current_user.id, user.id).first + friend.status = true + if friend.save + @add_friend = Friendship.new(user_id: current_user.id, friend_id: user.id, status: true) + @add_friend.save + redirect_to user_path(current_user), notice: 'Accepted' + else + redirect_to user_path(current_user), alert: 'Rejected' + end + end + + def destroy + user = User.find(params[:friend_id]) + first_friend = Friendship.where('friend_id = ? and user_id = ?', user.id, current_user.id).first + second_friend = Friendship.where('friend_id = ? and user_id = ?', current_user.id, user.id).first + if !first_friend.nil? + if first_friend.delete + redirect_to user_path(current_user), notice: 'Rejected' + else + redirect_to user_path(current_user), alert: 'Failed' + end + elsif !second_friend.nil? + if second_friend.delete + redirect_to user_path(current_user), notice: 'Rejected' + else + redirect_to user_path(current_user), alert: 'Failed' + end + end end end diff --git a/app/helpers/api/v1/auth_helper.rb b/app/helpers/api/v1/auth_helper.rb new file mode 100644 index 0000000000..890f4b1018 --- /dev/null +++ b/app/helpers/api/v1/auth_helper.rb @@ -0,0 +1,2 @@ +module Api::V1::AuthHelper +end diff --git a/app/helpers/api/v1/base_helper.rb b/app/helpers/api/v1/base_helper.rb new file mode 100644 index 0000000000..83a0f4150b --- /dev/null +++ b/app/helpers/api/v1/base_helper.rb @@ -0,0 +1,2 @@ +module Api::V1::BaseHelper +end diff --git a/app/helpers/api/v1/comments_helper.rb b/app/helpers/api/v1/comments_helper.rb new file mode 100644 index 0000000000..29b22cd98b --- /dev/null +++ b/app/helpers/api/v1/comments_helper.rb @@ -0,0 +1,2 @@ +module Api::V1::CommentsHelper +end diff --git a/app/helpers/api/v1/posts_helper.rb b/app/helpers/api/v1/posts_helper.rb new file mode 100644 index 0000000000..07d0f18233 --- /dev/null +++ b/app/helpers/api/v1/posts_helper.rb @@ -0,0 +1,2 @@ +module Api::V1::PostsHelper +end diff --git a/app/helpers/api/v1/register_helper.rb b/app/helpers/api/v1/register_helper.rb new file mode 100644 index 0000000000..a69cf2f8e4 --- /dev/null +++ b/app/helpers/api/v1/register_helper.rb @@ -0,0 +1,2 @@ +module Api::V1::RegisterHelper +end diff --git a/app/helpers/api/v1/registration_helper.rb b/app/helpers/api/v1/registration_helper.rb new file mode 100644 index 0000000000..a038687be0 --- /dev/null +++ b/app/helpers/api/v1/registration_helper.rb @@ -0,0 +1,2 @@ +module Api::V1::RegistrationHelper +end diff --git a/app/helpers/api_helper.rb b/app/helpers/api_helper.rb new file mode 100644 index 0000000000..1f82fcf9b4 --- /dev/null +++ b/app/helpers/api_helper.rb @@ -0,0 +1,2 @@ +module ApiHelper +end diff --git a/app/helpers/friendships_helper.rb b/app/helpers/friendships_helper.rb new file mode 100644 index 0000000000..64f89ba620 --- /dev/null +++ b/app/helpers/friendships_helper.rb @@ -0,0 +1,2 @@ +module FriendshipsHelper +end diff --git a/app/helpers/user_helper.rb b/app/helpers/user_helper.rb new file mode 100644 index 0000000000..a41e0ee0c7 --- /dev/null +++ b/app/helpers/user_helper.rb @@ -0,0 +1,12 @@ +module UserHelper + def friends?(user) + Friendship.exists?(user_id: current_user.id, friend_id: user) + end + + def sent_requests + @requested_friends = [] + @sent_requests = Friendship.where('user_id = ? and status = ?', current_user.id, false) + @sent_requests.each { |u| @requested_friends << User.find(u.friend_id) } + @requested_friends + end +end diff --git a/app/models/friendship.rb b/app/models/friendship.rb new file mode 100644 index 0000000000..b334b963e5 --- /dev/null +++ b/app/models/friendship.rb @@ -0,0 +1,4 @@ +class Friendship < ApplicationRecord + belongs_to :user + belongs_to :friend, class_name: 'User' +end diff --git a/app/models/post.rb b/app/models/post.rb index 39ebdc54cb..598ae9ee40 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -1,10 +1,8 @@ class Post < ApplicationRecord - validates :content, presence: true, length: { maximum: 1000, - too_long: '1000 characters in post is the maximum allowed.' } + validates :content, presence: true, length: { maximum: 500, + too_long: '500 characters in post is the maximum allowed.' } belongs_to :user - - scope :ordered_by_most_recent, -> { order(created_at: :desc) } has_many :comments, dependent: :destroy has_many :likes, dependent: :destroy end diff --git a/app/models/user.rb b/app/models/user.rb index e97f1363c0..cafe76c968 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -9,4 +9,11 @@ class User < ApplicationRecord has_many :posts has_many :comments, dependent: :destroy has_many :likes, dependent: :destroy + + has_many :friendships + has_many :inverse_friendships, class_name: 'Friendship', foreign_key: 'friend_id' + + def friend_requests + inverse_friendships.map { |friendship| friendship.user unless friendship.status }.compact + end end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index e5fdd63777..2f7b2428bc 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -17,7 +17,13 @@
+ <% if current_user %> + + <% end %> + <% if current_user %> <%= link_to 'Sign out', destroy_user_session_path, method: :delete %> <% else %> diff --git a/app/views/posts/_post.html.erb b/app/views/posts/_post.html.erb index 271625b734..45e2665ed1 100644 --- a/app/views/posts/_post.html.erb +++ b/app/views/posts/_post.html.erb @@ -5,11 +5,13 @@
<%= post.content %>
+
Comments:<%= post.comments.count %>
<%= "Name: #{@user.name}" %>
+ <% if current_user.id != @user.id %> + <% if !friends?(@user.id) %> + <%= button_to 'Add friend', {:controller => "friendships", :action => "create", :friend_id => @user.id} , :method=>:post %> + + <% end %> + + <% end %> +Recent posts:
<%= render @posts %>
+
+- <%= friend.name %>
+ <%= button_to "Remove Request", {:controller => "users", :action => "destroy", :friend_id => friend.id}, :method=>:delete %>
+ <% end %>
+ <% end %>
+
+Pending Friend Requests:
+ <% sent_requests.each do |friend| %> ++ +
+- <%= friend.name %>
+ <%= button_to "Accept Request", {:controller => "users", :action => "confirm", :friend_id => friend.id}, :method=>:post %>
+ <%= button_to "Reject Request", {:controller => "users", :action => "destroy", :friend_id => friend.id}, :method=>:delete %>
+ <% end %>
+
+ <% end %> +Recived Friend Requests:
+ <% current_user.friend_requests.each do |friend| %> ++ +
All Friends:
++ <% @all_friends.each do |f| %> +- <%= f.name %>
+ <% end %>
+