From a13efc322fcefcee405cc709dfc551d2e1dc18a2 Mon Sep 17 00:00:00 2001 From: Ibrahim MA Date: Wed, 23 Mar 2022 09:59:41 -0700 Subject: [PATCH 1/3] Initial commit for solution branch --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 7db80e4..5098999 100644 --- a/README.md +++ b/README.md @@ -22,3 +22,7 @@ Things you may want to cover: * Deployment instructions * ... + + + +* Initizle comment for solution branch! \ No newline at end of file From 3a10d7b338cb0c9069dc1e747617b62ed995255a Mon Sep 17 00:00:00 2001 From: Ibrahim MA Date: Wed, 23 Mar 2022 23:45:08 -0700 Subject: [PATCH 2/3] Create Models, Controllers, Views and updating the routes --- Gemfile | 10 ++- Gemfile.lock | 39 +++++++++++ README.md | 62 ++++++++++++++++- app/assets/images/idea.png | Bin 0 -> 57414 bytes .../{images/.keep => stylesheets/ideas.scss} | 0 app/assets/stylesheets/likes.scss | 0 app/assets/stylesheets/reviews.scss | 0 app/assets/stylesheets/sessions.scss | 0 app/assets/stylesheets/users.scss | 0 app/controllers/application_controller.rb | 20 +++++- app/controllers/ideas_controller.rb | 61 +++++++++++++++++ app/controllers/likes_controller.rb | 29 ++++++++ app/controllers/reviews_controller.rb | 31 +++++++++ app/controllers/sessions_controller.rb | 22 ++++++ app/controllers/users_controller.rb | 16 +++++ app/helpers/ideas_helper.rb | 2 + app/helpers/likes_helper.rb | 2 + app/helpers/reviews_helper.rb | 2 + app/helpers/sessions_helper.rb | 2 + app/helpers/users_helper.rb | 2 + app/models/ability.rb | 28 ++++++++ app/models/idea.rb | 12 ++++ app/models/like.rb | 4 ++ app/models/review.rb | 7 ++ app/models/user.rb | 10 +++ app/views/ideas/_form.html.erb | 20 ++++++ app/views/ideas/edit.html.erb | 2 + app/views/ideas/index.html.erb | 28 ++++++++ app/views/ideas/new.html.erb | 2 + app/views/ideas/show.html.erb | 64 ++++++++++++++++++ app/views/layouts/application.html.erb | 39 ++++++++++- app/views/sessions/new.html.erb | 15 ++++ app/views/users/new.html.erb | 24 +++++++ config/routes.rb | 13 ++-- db/migrate/20220323185500_create_users.rb | 12 ++++ db/migrate/20220323185506_create_ideas.rb | 10 +++ db/migrate/20220323213652_create_likes.rb | 10 +++ db/migrate/20220323214639_create_reviews.rb | 11 +++ .../20220324040612_add_user_to_ideas.rb | 6 ++ db/schema.rb | 60 ++++++++++++++++ 40 files changed, 667 insertions(+), 10 deletions(-) create mode 100644 app/assets/images/idea.png rename app/assets/{images/.keep => stylesheets/ideas.scss} (100%) create mode 100644 app/assets/stylesheets/likes.scss create mode 100644 app/assets/stylesheets/reviews.scss create mode 100644 app/assets/stylesheets/sessions.scss create mode 100644 app/assets/stylesheets/users.scss create mode 100644 app/controllers/ideas_controller.rb create mode 100644 app/controllers/likes_controller.rb create mode 100644 app/controllers/reviews_controller.rb create mode 100644 app/controllers/sessions_controller.rb create mode 100644 app/controllers/users_controller.rb create mode 100644 app/helpers/ideas_helper.rb create mode 100644 app/helpers/likes_helper.rb create mode 100644 app/helpers/reviews_helper.rb create mode 100644 app/helpers/sessions_helper.rb create mode 100644 app/helpers/users_helper.rb create mode 100644 app/models/ability.rb create mode 100644 app/models/idea.rb create mode 100644 app/models/like.rb create mode 100644 app/models/review.rb create mode 100644 app/models/user.rb create mode 100644 app/views/ideas/_form.html.erb create mode 100644 app/views/ideas/edit.html.erb create mode 100644 app/views/ideas/index.html.erb create mode 100644 app/views/ideas/new.html.erb create mode 100644 app/views/ideas/show.html.erb create mode 100644 app/views/sessions/new.html.erb create mode 100644 app/views/users/new.html.erb create mode 100644 db/migrate/20220323185500_create_users.rb create mode 100644 db/migrate/20220323185506_create_ideas.rb create mode 100644 db/migrate/20220323213652_create_likes.rb create mode 100644 db/migrate/20220323214639_create_reviews.rb create mode 100644 db/migrate/20220324040612_add_user_to_ideas.rb create mode 100644 db/schema.rb diff --git a/Gemfile b/Gemfile index b460be7..94ca855 100644 --- a/Gemfile +++ b/Gemfile @@ -34,7 +34,7 @@ gem "jbuilder" # gem "kredis" # Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] -# gem "bcrypt", "~> 3.1.7" +gem "bcrypt", "~> 3.1.7" # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ] @@ -42,8 +42,13 @@ gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ] # Reduces boot times through caching; required in config/boot.rb gem "bootsnap", require: false +gem 'pry-rails' +gem 'cancancan' +gem 'bootstrap', '~> 5.1.3' +gem 'jquery-rails' + # Use Sass to process CSS -# gem "sassc-rails" +gem "sassc-rails" # Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] # gem "image_processing", "~> 1.2" @@ -51,6 +56,7 @@ gem "bootsnap", require: false group :development, :test do # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem gem "debug", platforms: %i[ mri mingw x64_mingw ] + gem 'faker' end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index b6c2b90..a0e6807 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -66,10 +66,19 @@ GEM i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) + autoprefixer-rails (10.4.2.0) + execjs (~> 2) + bcrypt (3.1.17) bindex (0.8.1) bootsnap (1.11.1) msgpack (~> 1.2) + bootstrap (5.1.3) + autoprefixer-rails (>= 9.1.0) + popper_js (>= 2.9.3, < 3) + sassc-rails (>= 2.0.0) builder (3.2.4) + cancancan (3.3.0) + coderay (1.1.3) concurrent-ruby (1.1.10) crass (1.0.6) debug (1.4.0) @@ -77,6 +86,10 @@ GEM reline (>= 0.2.7) digest (3.1.0) erubi (1.10.0) + execjs (2.8.1) + faker (2.20.0) + i18n (>= 1.8.11, < 2) + ffi (1.15.5) globalid (1.0.0) activesupport (>= 5.0) i18n (1.10.0) @@ -91,6 +104,10 @@ GEM jbuilder (2.11.5) actionview (>= 5.0.0) activesupport (>= 5.0.0) + jquery-rails (4.4.0) + rails-dom-testing (>= 1, < 3) + railties (>= 4.2.0) + thor (>= 0.14, < 2.0) loofah (2.15.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) @@ -120,6 +137,12 @@ GEM nokogiri (1.13.3-x86_64-linux) racc (~> 1.4) pg (1.3.4) + popper_js (2.9.3) + pry (0.14.1) + coderay (~> 1.1) + method_source (~> 1.0) + pry-rails (0.3.9) + pry (>= 0.10.4) puma (5.6.2) nio4r (~> 2.0) racc (1.6.0) @@ -155,6 +178,14 @@ GEM rake (13.0.6) reline (0.3.1) io-console (~> 0.5) + sassc (2.4.0) + ffi (~> 1.9) + sassc-rails (2.1.2) + railties (>= 4.0.0) + sassc (>= 2.0) + sprockets (> 3.0) + sprockets-rails + tilt sprockets (4.0.3) concurrent-ruby (~> 1.0) rack (> 1, < 3) @@ -166,6 +197,7 @@ GEM railties (>= 6.0.0) strscan (3.0.1) thor (1.2.1) + tilt (2.0.10) timeout (0.2.0) turbo-rails (1.0.1) actionpack (>= 6.0.0) @@ -186,13 +218,20 @@ PLATFORMS x86_64-linux DEPENDENCIES + bcrypt (~> 3.1.7) bootsnap + bootstrap (~> 5.1.3) + cancancan debug + faker importmap-rails jbuilder + jquery-rails pg (~> 1.1) + pry-rails puma (~> 5.0) rails (~> 7.0.2, >= 7.0.2.3) + sassc-rails sprockets-rails stimulus-rails turbo-rails diff --git a/README.md b/README.md index 5098999..7036c8f 100644 --- a/README.md +++ b/README.md @@ -24,5 +24,65 @@ Things you may want to cover: * ... +---------------------------------------------------------------------------------------------------------------------------- +I added this comment to check the new branch "solution" is working on GitHub. +* Initial commit for solution branch! +----------------------------------------------------------------------------------------------------------------------------- +# Web App --> Idea Factory +* mkdir quiz2 +* cd quiz2 +* rails new IdeaFactory ---> BUILD A NEW WEB APP +* cd IdeaFactory +* git status => ON MAIN BRANCH +* git add . +* git commit -m "Set up new app" +* git remote add origin https://github.com/abe2dev/IdeaFactory.git (THIS ONE DIDN'T WORK) SO WE HAD TO DELETE IT (git remote remove origin) +* git remote add ssh git@github.com:abe2dev/IdeaFactory.git +* git push -u ssh main +* git status +* git checkout -b solution +* WE TEST OUR NEW BRANCH BY PUSHING A COMMIT BEEN MADE ON README.md +----------------------------------------------------------------------------------------------------------- +TEST THE VALIDATIONS: +* Run --> rails c +* Model name + .all --> to make sure it's empty, in this quiz we run --> Idea.all +* Model name + create(we pass the validations we put in the migration file), in this quiz --> Idea.create(title:"", description:"hello there!") --> I left the title empty to make sure the validation of the title should be presence is working! +* then we give the variable here a name which in this quiz --> i=Idea.create(title:"", description:"hello there!") +* Then we will run --> i.errors.full_messages --> to see our errors with full messages +--------------------------------------------------------------------------------------------------------------- +MODELS: +rails g model user +rails g model idea title:string description:text +rails g model like +rails g model review +rails g model join +rails g cancan:ability + +* WE EDIT OUR VALIDATIONS IF IT'S REQUIRED THEN RUN THE COMMAND "rails db:migrate" + + +CONTROLLERS: +rails g controller ideas +rails g controller joins +rails g controller likes +rails g controller reviews +rails g controller sessions +rails g controller users + + +VIEWS: +ideas: +_form & edit & idex & new & show.html.erb + +sessions: +new.html.erb + +users: +new.html.erb + + +DB/MIGRATE: +* RUN THE "rails db:migrate" after creating them +rails g migration AddUserReferencesToIdea +rails g migration AddIdeaReferencesToReview -* Initizle comment for solution branch! \ No newline at end of file diff --git a/app/assets/images/idea.png b/app/assets/images/idea.png new file mode 100644 index 0000000000000000000000000000000000000000..1a1147aae97912575debdacaa686e7230ffd4f3f GIT binary patch literal 57414 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 W&|%);_;4g993ux5u?)k%BmV=Ik)DD8 literal 0 HcmV?d00001 diff --git a/app/assets/images/.keep b/app/assets/stylesheets/ideas.scss similarity index 100% rename from app/assets/images/.keep rename to app/assets/stylesheets/ideas.scss diff --git a/app/assets/stylesheets/likes.scss b/app/assets/stylesheets/likes.scss new file mode 100644 index 0000000..e69de29 diff --git a/app/assets/stylesheets/reviews.scss b/app/assets/stylesheets/reviews.scss new file mode 100644 index 0000000..e69de29 diff --git a/app/assets/stylesheets/sessions.scss b/app/assets/stylesheets/sessions.scss new file mode 100644 index 0000000..e69de29 diff --git a/app/assets/stylesheets/users.scss b/app/assets/stylesheets/users.scss new file mode 100644 index 0000000..e69de29 diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 09705d1..1450813 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,2 +1,20 @@ class ApplicationController < ActionController::Base -end + + private + + def current_user + current_user ||= User.find_by_id session[:user_id] # ||= will only assign @current_user if it is nil. Otherwise continue using it's + end + helper_method :current_user + + def user_signed_in? + current_user.present? + end + helper_method :user_signed_in? + + def authenticate_user! + redirect_to new_session_path, {alert: "You need to be signed in first!", status: 303} unless user_signed_in? + end + helper_method :authenticate_user! + +end \ No newline at end of file diff --git a/app/controllers/ideas_controller.rb b/app/controllers/ideas_controller.rb new file mode 100644 index 0000000..5970f76 --- /dev/null +++ b/app/controllers/ideas_controller.rb @@ -0,0 +1,61 @@ +class IdeasController < ApplicationController + before_action :authenticate_user!, except: [:index, :show] + before_action :get_idea!, only: [:show, :edit, :update, :destroy] + before_action :authorize!, only: [:edit, :update, :destroy] + + def new + @idea = Idea.new + end + + def create + @idea = Idea.new idea_params + @idea.user = current_user + if @idea.save + redirect_to ideas_path(@idea), { status: 303, notice: 'Idea created' } + else + flash.alert = @idea.errors.full_messages.join(', ') + render :new, status: 303 + end + end + + def index + @ideas = Idea.all.order('updated_at DESC') + end + + def show + @review = Review.new + @reviews = @idea.reviews.order(created_at: :desc) + @like = @idea.likes.find_by(user: current_user) + end + + def edit + + end + + def update + id = params[:id] + @idea = Idea.find(id) + if @idea.update(params.require(:idea).permit(:title, :description)) + redirect_to idea_path(@idea), status: 303 + else + render :edit, status: 303 + end + end + + def destroy + id = params[:id] + @idea = Idea.find(id) + @idea.destroy + redirect_to ideas_path, status: 303 + end + + private + + def get_idea! + @idea = Idea.find(params[:id]) + end + + def authorize! + redirect_to root_path, status: 303, alert: 'Not Authorized' unless can?(:crud, @idea) + end + end \ No newline at end of file diff --git a/app/controllers/likes_controller.rb b/app/controllers/likes_controller.rb new file mode 100644 index 0000000..a942ee7 --- /dev/null +++ b/app/controllers/likes_controller.rb @@ -0,0 +1,29 @@ +class LikesController < ApplicationController + before_action :authenticate_user!, only: [:create, :destroy] + + def create + idea = Idea.find params[:idea_id] + like = Like.new( user: current_user, idea: idea ) + + if can?(:like, idea) + if like.save + redirect_to idea_path(idea), { notice: "Idea Liked", status: 303 } + else + redirect_to root_path, { alert: like.errors.full_messages.join(", "), status: 303 } + end + else + redirect_to root_path, { alert: "You can't like your own idea....", status: 303 } + end + end + + def destroy + like = Like.find params[:id] + + if can?(:destroy, like) + like.destroy + redirect_to root_path, { notice: "Idea unliked", status: 303 } + else + redirect_to root_path, {alert: "You can't unlike because not authorized!", status: 303 } + end + end +end \ No newline at end of file diff --git a/app/controllers/reviews_controller.rb b/app/controllers/reviews_controller.rb new file mode 100644 index 0000000..ec28f72 --- /dev/null +++ b/app/controllers/reviews_controller.rb @@ -0,0 +1,31 @@ +class ReviewsController < ApplicationController + + def create + @idea = Idea.find(params[:idea_id]) + @review = Review.new review_params + @review.idea = @idea + @review.user = current_user + if @review.save + redirect_to idea_path(@idea) + else + @reviews = @idea.reviews.order(created_at: :desc) + render 'ideas/show', status: 303 + end + end + + def destroy + @review = Review.find params[:id] + if can?(:crud, @review) + @review.destroy + redirect_to idea_path(@review.idea), status: 303 + else + head :unauthorized + end + end + + private + + def review_params + params.require(:review).permit(:body) + end +end \ No newline at end of file diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 0000000..afe2549 --- /dev/null +++ b/app/controllers/sessions_controller.rb @@ -0,0 +1,22 @@ +class SessionsController < ApplicationController + def new + end + + def create + user = User.find_by_email params[:email] + + if user&.authenticate params[:password] + session[:user_id] = user.id + flash[:success] = "User Logged In" + redirect_to ideas_path, status: 303 + else + flash[:warning] = "Couldn't Log In, Please Try Again" + render :new, status: 303 + end + end + + def destroy + session[:user_id] = nil + redirect_to ideas_path, status: 303 + end +end \ No newline at end of file diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100644 index 0000000..73f4347 --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,16 @@ +class UsersController < ApplicationController + def new + @user = User.new + end + + def create + @user = User.new params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation) + if @user.save + flash.delete(:warning) + redirect_to ideas_path, status: 303 + else + flash[:warning] = "Unable to Create User" + render :new, status: 303 + end + end +end \ No newline at end of file diff --git a/app/helpers/ideas_helper.rb b/app/helpers/ideas_helper.rb new file mode 100644 index 0000000..0a60b4e --- /dev/null +++ b/app/helpers/ideas_helper.rb @@ -0,0 +1,2 @@ +module IdeasHelper +end diff --git a/app/helpers/likes_helper.rb b/app/helpers/likes_helper.rb new file mode 100644 index 0000000..a78a759 --- /dev/null +++ b/app/helpers/likes_helper.rb @@ -0,0 +1,2 @@ +module LikesHelper +end diff --git a/app/helpers/reviews_helper.rb b/app/helpers/reviews_helper.rb new file mode 100644 index 0000000..682b7b1 --- /dev/null +++ b/app/helpers/reviews_helper.rb @@ -0,0 +1,2 @@ +module ReviewsHelper +end diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb new file mode 100644 index 0000000..309f8b2 --- /dev/null +++ b/app/helpers/sessions_helper.rb @@ -0,0 +1,2 @@ +module SessionsHelper +end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb new file mode 100644 index 0000000..2310a24 --- /dev/null +++ b/app/helpers/users_helper.rb @@ -0,0 +1,2 @@ +module UsersHelper +end diff --git a/app/models/ability.rb b/app/models/ability.rb new file mode 100644 index 0000000..3174ebc --- /dev/null +++ b/app/models/ability.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +class Ability + include CanCan::Ability + + def initialize(user) + + user ||= User.new + + alias_action :create, :read, :update, :destroy, to: :crud + + can :crud, Idea do |idea| + idea.user == user + end + + can :crud, Review do |review| + review.user == user + end + + can :like, Idea do |idea| + user.present? && idea.user != user + end + + can :destroy, Like do |like| + like.user == user + end + end +end \ No newline at end of file diff --git a/app/models/idea.rb b/app/models/idea.rb new file mode 100644 index 0000000..24d8349 --- /dev/null +++ b/app/models/idea.rb @@ -0,0 +1,12 @@ +class Idea < ApplicationRecord + has_many :reviews, dependent: :destroy + + has_many :likes, dependent: :destroy + has_many :likers, through: :likes, source: :user + belongs_to :user + + validates :title, presence: true + validates :description, presence: true + + +end \ No newline at end of file diff --git a/app/models/like.rb b/app/models/like.rb new file mode 100644 index 0000000..3c411aa --- /dev/null +++ b/app/models/like.rb @@ -0,0 +1,4 @@ +class Like < ApplicationRecord + belongs_to :user + belongs_to :idea +end \ No newline at end of file diff --git a/app/models/review.rb b/app/models/review.rb new file mode 100644 index 0000000..271ab68 --- /dev/null +++ b/app/models/review.rb @@ -0,0 +1,7 @@ +class Review < ApplicationRecord + belongs_to :idea + belongs_to :user + + validates :body, presence: true + validates :rating, {numericality: { greater_than_or_equal_to: 1, less_than_or_equal_to: 5 }} +end \ No newline at end of file diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000..373763b --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,10 @@ +class User < ApplicationRecord + has_secure_password + has_many :ideas + has_many :reviews + + has_many :likes, dependent: :destroy + has_many :liked_ideas, through: :likes, source: :idea + + validates :email, presence: true, uniqueness: true, format: /\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i +end \ No newline at end of file diff --git a/app/views/ideas/_form.html.erb b/app/views/ideas/_form.html.erb new file mode 100644 index 0000000..a747978 --- /dev/null +++ b/app/views/ideas/_form.html.erb @@ -0,0 +1,20 @@ +<% if @idea.errors.any? %> +
    + <% @idea.errors.full_messages.each do |msg|%> +
  • <%= msg%>
  • + <% end %> +
+<% end%> + + +<%= form_for @idea do |f|%> +
+ <%= f.label :title %> + <%= f.text_field :title,class:'form-control'%> +
+
+ <%= f.label :description %> + <%= f.text_area :description,class:'form-control'%> +
+<%= f.submit :submit, class:"btn btn-primary" %> +<% end%> \ No newline at end of file diff --git a/app/views/ideas/edit.html.erb b/app/views/ideas/edit.html.erb new file mode 100644 index 0000000..4a207d9 --- /dev/null +++ b/app/views/ideas/edit.html.erb @@ -0,0 +1,2 @@ +

Create Your Idea

+<%= render "form"%> \ No newline at end of file diff --git a/app/views/ideas/index.html.erb b/app/views/ideas/index.html.erb new file mode 100644 index 0000000..c8a173b --- /dev/null +++ b/app/views/ideas/index.html.erb @@ -0,0 +1,28 @@ +<% @ideas.each do |idea| %> +
+

<%= link_to idea.title, idea_path(idea) %>

+

<%= idea.description %>

+
+ By <%= idea.user&.first_name %> + <% @like = idea.likes.find_by(user: current_user)%> + <% if @like.present? && can?(:destroy, @like) %> + <%= link_to( + "Unlike", + like_path(@like), + class:"btn btn-danger ", + method: :delete + ) %> + <% else can?(:like, idea) %> + <%= link_to( + "Like", + idea_likes_path(idea), + class:"btn btn-success ", + method: :post + ) %> + <% end %>| + + (<%= pluralize(idea.likes.count, "like") %>) + +
+
+<% end %> \ No newline at end of file diff --git a/app/views/ideas/new.html.erb b/app/views/ideas/new.html.erb new file mode 100644 index 0000000..4a207d9 --- /dev/null +++ b/app/views/ideas/new.html.erb @@ -0,0 +1,2 @@ +

Create Your Idea

+<%= render "form"%> \ No newline at end of file diff --git a/app/views/ideas/show.html.erb b/app/views/ideas/show.html.erb new file mode 100644 index 0000000..7058eb4 --- /dev/null +++ b/app/views/ideas/show.html.erb @@ -0,0 +1,64 @@ +

<%= @idea.title %>

+

<%= @idea.description %>

+ +<% if can?(:crud, @idea)%> +<%= link_to "Edit", edit_idea_path(@idea), class:"btn btn-warning " %> +<%= link_to "Delete", idea_path(@idea), class:"btn btn-danger ", method: :delete, data: {confirm: "Are you sure?"} %> +<% end %> +
+<%= form_with(model: [@idea, @review], local: true) do |f| %> +<% if @review.errors.any? %> +
    + <% @review.errors.full_messages.each do |msg|%> +
  • <%= msg %>
  • + <% end %> +
+<% end %> + +
+ + <%= f.text_area( + :body, + cols: 50, + rows: 5, + placeholder: "What are your review?", + class: "form-control" + ) %> +
+<%= f.submit "Review", class:"btn btn-primary" %> +<% end %> + +
+ +
    +<% if @reviews!= nil%> + <% @reviews.each do |review| %> +
  • +

    + <%= review.body %>
    + <% if can?(:crud, review)%> + + <%= button_to( + "Delete", + idea_review_path(@idea, review), + method: :delete, + data: { + confirm: "Are you sure?" + }, + class: "btn btn-danger" + ) %> + + | + <%end%> + + Reviewed <%= time_ago_in_words(review.created_at) %> ago + + | + + user: <%= review.user&.full_name %> + +

    +
  • + <% end %> +<% end %> +
\ No newline at end of file diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 2a554b5..f77e0a9 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -1,6 +1,10 @@ +
+ <%= image_tag("idea.png", width:"100",class:"image ml-4")%> +
+ IdeaFactory <%= csrf_meta_tags %> @@ -10,7 +14,38 @@ <%= javascript_importmap_tags %> - + + <% flash.each do |type, message|%> +
+ <%= message%> +
+ <% end%> +
+
Idea Factory
+ +
+ + +
+ <%= yield %> - + \ No newline at end of file diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb new file mode 100644 index 0000000..798d35e --- /dev/null +++ b/app/views/sessions/new.html.erb @@ -0,0 +1,15 @@ +

+ Sign In +

+ +<%= form_with url: session_path, local: true do |f|%> +
+ <%= f.label :email %> + <%= f.email_field :email,class:'form-control'%> +
+
+ <%= f.label :password %> + <%= f.password_field :password,class:'form-control'%> +
+<%= f.submit "Sign In", class:"btn btn-primary" %> +<% end%> \ No newline at end of file diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb new file mode 100644 index 0000000..52450bf --- /dev/null +++ b/app/views/users/new.html.erb @@ -0,0 +1,24 @@ +

Sing Up

+<%= form_with model: @user, local: true do |f|%> +
+ <%= f.label :first_name %> + <%= f.text_field :first_name,class:'form-control'%> +
+
+ <%= f.label :last_name %> + <%= f.text_field :last_name,class:'form-control'%> +
+
+ <%= f.label :email %> + <%= f.email_field :email,class:'form-control'%> +
+
+ <%= f.label :password %> + <%= f.password_field :password,class:'form-control'%> +
+
+ <%= f.label :password_confirmation %> + <%= f.password_field :password_confirmation,class:'form-control'%> +
+<%= f.submit :submit, class:"btn btn-primary" %> +<% end%> \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 262ffd5..774adae 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,11 @@ Rails.application.routes.draw do - # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html + + root 'ideas#index' + resources :ideas, except: [:index] do + resources :likes, shallow: true, only: [:create, :destroy] + resources :reviews, only: [:create, :destroy] + end - # Defines the root path route ("/") - # root "articles#index" -end + resources :users, only: [:new, :create, :edit, :update] + resource :session, only: [:new, :create, :destroy] +end \ No newline at end of file diff --git a/db/migrate/20220323185500_create_users.rb b/db/migrate/20220323185500_create_users.rb new file mode 100644 index 0000000..6352519 --- /dev/null +++ b/db/migrate/20220323185500_create_users.rb @@ -0,0 +1,12 @@ +class CreateUsers < ActiveRecord::Migration[6.0] + def change + create_table :users do |t| + t.string :first_name + t.string :last_name + t.string :email, index: {unique: true} + t.string :password_digest + + t.timestamps + end + end +end \ No newline at end of file diff --git a/db/migrate/20220323185506_create_ideas.rb b/db/migrate/20220323185506_create_ideas.rb new file mode 100644 index 0000000..83f64b2 --- /dev/null +++ b/db/migrate/20220323185506_create_ideas.rb @@ -0,0 +1,10 @@ +class CreateIdeas < ActiveRecord::Migration[6.0] + def change + create_table :ideas do |t| + t.string :title + t.text :description + + t.timestamps + end + end +end \ No newline at end of file diff --git a/db/migrate/20220323213652_create_likes.rb b/db/migrate/20220323213652_create_likes.rb new file mode 100644 index 0000000..a0d94c3 --- /dev/null +++ b/db/migrate/20220323213652_create_likes.rb @@ -0,0 +1,10 @@ +class CreateLikes < ActiveRecord::Migration[6.0] + def change + create_table :likes do |t| + t.references :user, foreign_key: true + t.references :idea, foreign_key: true + + t.timestamps + end + end +end \ No newline at end of file diff --git a/db/migrate/20220323214639_create_reviews.rb b/db/migrate/20220323214639_create_reviews.rb new file mode 100644 index 0000000..5ff4d93 --- /dev/null +++ b/db/migrate/20220323214639_create_reviews.rb @@ -0,0 +1,11 @@ +class CreateReviews < ActiveRecord::Migration[6.0] + def change + create_table :reviews do |t| + t.text :body + t.references :idea, foreign_key: true + t.references :user, foreign_key: true + + t.timestamps + end + end +end \ No newline at end of file diff --git a/db/migrate/20220324040612_add_user_to_ideas.rb b/db/migrate/20220324040612_add_user_to_ideas.rb new file mode 100644 index 0000000..ae6a146 --- /dev/null +++ b/db/migrate/20220324040612_add_user_to_ideas.rb @@ -0,0 +1,6 @@ +class AddUserToIdeas < ActiveRecord::Migration[7.0] + def change + + add_reference :ideas, :user, null: false, foreign_key: true + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 0000000..6fbac18 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,60 @@ +# 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. +# +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema[7.0].define(version: 2022_03_24_040612) do + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + + create_table "ideas", force: :cascade do |t| + t.string "title" + t.text "description" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.bigint "user_id", null: false + t.index ["user_id"], name: "index_ideas_on_user_id" + end + + create_table "likes", force: :cascade do |t| + t.integer "user_id" + t.integer "idea_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["idea_id"], name: "index_likes_on_idea_id" + t.index ["user_id"], name: "index_likes_on_user_id" + end + + create_table "reviews", force: :cascade do |t| + t.text "body" + t.integer "idea_id" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["idea_id"], name: "index_reviews_on_idea_id" + t.index ["user_id"], name: "index_reviews_on_user_id" + end + + create_table "users", force: :cascade do |t| + t.string "first_name" + t.string "last_name" + t.string "email" + t.string "password_digest" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["email"], name: "index_users_on_email", unique: true + end + + add_foreign_key "ideas", "users" + add_foreign_key "likes", "ideas" + add_foreign_key "likes", "users" + add_foreign_key "reviews", "ideas" + add_foreign_key "reviews", "users" +end From c997b0a32ebda8cb2a1e7935088ede7162ff1e6d Mon Sep 17 00:00:00 2001 From: ibrahim Date: Sun, 3 Apr 2022 20:12:55 -0700 Subject: [PATCH 3/3] delete README.md file --- README.md | 88 ------------------------------------------------------- 1 file changed, 88 deletions(-) delete mode 100644 README.md diff --git a/README.md b/README.md deleted file mode 100644 index 7036c8f..0000000 --- a/README.md +++ /dev/null @@ -1,88 +0,0 @@ -# README - -This README would normally document whatever steps are necessary to get the -application up and running. - -Things you may want to cover: - -* Ruby version - -* System dependencies - -* Configuration - -* Database creation - -* Database initialization - -* How to run the test suite - -* Services (job queues, cache servers, search engines, etc.) - -* Deployment instructions - -* ... - - ----------------------------------------------------------------------------------------------------------------------------- -I added this comment to check the new branch "solution" is working on GitHub. -* Initial commit for solution branch! ------------------------------------------------------------------------------------------------------------------------------ -# Web App --> Idea Factory -* mkdir quiz2 -* cd quiz2 -* rails new IdeaFactory ---> BUILD A NEW WEB APP -* cd IdeaFactory -* git status => ON MAIN BRANCH -* git add . -* git commit -m "Set up new app" -* git remote add origin https://github.com/abe2dev/IdeaFactory.git (THIS ONE DIDN'T WORK) SO WE HAD TO DELETE IT (git remote remove origin) -* git remote add ssh git@github.com:abe2dev/IdeaFactory.git -* git push -u ssh main -* git status -* git checkout -b solution -* WE TEST OUR NEW BRANCH BY PUSHING A COMMIT BEEN MADE ON README.md ------------------------------------------------------------------------------------------------------------ -TEST THE VALIDATIONS: -* Run --> rails c -* Model name + .all --> to make sure it's empty, in this quiz we run --> Idea.all -* Model name + create(we pass the validations we put in the migration file), in this quiz --> Idea.create(title:"", description:"hello there!") --> I left the title empty to make sure the validation of the title should be presence is working! -* then we give the variable here a name which in this quiz --> i=Idea.create(title:"", description:"hello there!") -* Then we will run --> i.errors.full_messages --> to see our errors with full messages ---------------------------------------------------------------------------------------------------------------- -MODELS: -rails g model user -rails g model idea title:string description:text -rails g model like -rails g model review -rails g model join -rails g cancan:ability - -* WE EDIT OUR VALIDATIONS IF IT'S REQUIRED THEN RUN THE COMMAND "rails db:migrate" - - -CONTROLLERS: -rails g controller ideas -rails g controller joins -rails g controller likes -rails g controller reviews -rails g controller sessions -rails g controller users - - -VIEWS: -ideas: -_form & edit & idex & new & show.html.erb - -sessions: -new.html.erb - -users: -new.html.erb - - -DB/MIGRATE: -* RUN THE "rails db:migrate" after creating them -rails g migration AddUserReferencesToIdea -rails g migration AddIdeaReferencesToReview -