From 8a911efcc50612f343fa6c9b6baa39f7694199f3 Mon Sep 17 00:00:00 2001 From: Yarmolenko Daniil Date: Sun, 25 Nov 2018 15:23:00 +0200 Subject: [PATCH 1/2] homework 6 --- Gemfile | 1 + Gemfile.lock | 18 +++++++++++++++ app/assets/stylesheets/application.scss | 24 ++++++++++++++++++++ app/controllers/sessions_controller.rb | 4 +++- app/controllers/tasks_controller.rb | 23 ++++++++++++++++++- app/mailers/application_mailer.rb | 2 +- app/mailers/user_mailer.rb | 16 +++++++++++++ app/models/task.rb | 7 +++--- app/models/user.rb | 2 ++ app/views/sessions/_form.html.erb | 10 +++++--- app/views/tasks/index.html.erb | 12 ++++++++-- app/views/user_mailer/welcome_email.html.erb | 17 ++++++++++++++ app/views/user_mailer/welcome_email.text.erb | 9 ++++++++ config/application.rb | 3 +++ config/application.yml | 6 +++++ config/environment.rb | 10 ++++++++ config/environments/development.rb | 13 ++++++++++- config/environments/production.rb | 11 +++++++++ config/locales/en.yml | 2 +- config/routes.rb | 1 + db/migrate/20181110170834_create_users.rb | 3 ++- db/schema.rb | 2 ++ test/mailers/previews/user_mailer_preview.rb | 4 ++++ test/mailers/user_mailer_test.rb | 7 ++++++ 24 files changed, 193 insertions(+), 14 deletions(-) create mode 100644 app/mailers/user_mailer.rb create mode 100644 app/views/user_mailer/welcome_email.html.erb create mode 100644 app/views/user_mailer/welcome_email.text.erb create mode 100644 config/application.yml create mode 100644 test/mailers/previews/user_mailer_preview.rb create mode 100644 test/mailers/user_mailer_test.rb diff --git a/Gemfile b/Gemfile index ecea4a7..f981e25 100644 --- a/Gemfile +++ b/Gemfile @@ -3,6 +3,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby '2.5.1' +gem 'mailgun-ruby', require: 'mailgun' gem 'will_paginate' gem 'jquery-rails' gem 'bootstrap', '~> 4.1.3' diff --git a/Gemfile.lock b/Gemfile.lock index ee73330..31e3805 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -81,11 +81,15 @@ GEM coffee-script-source (1.12.2) concurrent-ruby (1.1.1) crass (1.0.4) + domain_name (0.5.20180417) + unf (>= 0.0.5, < 1.0.0) erubi (1.7.1) execjs (2.7.0) ffi (1.9.25) globalid (0.4.1) activesupport (>= 4.2.0) + http-cookie (1.0.3) + domain_name (~> 0.5) i18n (1.1.1) concurrent-ruby (~> 1.0) io-like (0.3.0) @@ -96,6 +100,7 @@ GEM rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) + json (1.8.6) listen (3.1.5) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) @@ -105,15 +110,20 @@ GEM nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) + mailgun-ruby (1.0.3) + json (~> 1.8) + rest-client (~> 1.6) marcel (0.3.3) mimemagic (~> 0.3.2) method_source (0.9.1) + mime-types (2.99.3) mimemagic (0.3.2) mini_mime (1.0.1) mini_portile2 (2.3.0) minitest (5.11.3) msgpack (1.2.4) multi_json (1.13.1) + netrc (0.11.0) nio4r (2.3.1) nokogiri (1.8.5) mini_portile2 (~> 2.3.0) @@ -152,6 +162,10 @@ GEM rb-inotify (0.9.10) ffi (>= 0.5.0, < 2) regexp_parser (1.2.0) + rest-client (1.8.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 3.0) + netrc (~> 0.7) ruby_dep (1.5.0) rubyzip (1.2.2) sass (3.6.0) @@ -191,6 +205,9 @@ GEM thread_safe (~> 0.1) uglifier (4.1.19) execjs (>= 0.3.0, < 3) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.5) web-console (3.7.0) actionview (>= 5.0) activemodel (>= 5.0) @@ -217,6 +234,7 @@ DEPENDENCIES jbuilder (~> 2.5) jquery-rails listen (>= 3.0.5, < 3.2) + mailgun-ruby puma (~> 3.11) rails (~> 5.2.1) sass-rails (~> 5.0) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 567f715..1f3c9f4 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -66,8 +66,17 @@ body { margin: 0 0 20px 0; } .input-group { + width: 100%; max-width: 500px; margin: 0 auto 20px; + .field_with_errors, .input-container { + width: 100%; + } + .error-message { + margin: 0; + font-size: 18px; + color: red; + } } } .list-container { @@ -143,6 +152,21 @@ body { margin: 0 auto; } + .share-form { + display: flex; + justify-content: center; + margin-bottom: 10px; + .share-input-container { + display: flex; + p { + margin: 0; + } + .share { + margin-right: 10px; + } + } + } + .bg-dark { background-color: #343a4069; } diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index edf9cc1..019d55e 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -7,7 +7,9 @@ def new def create @user = User.find_by(name: user_params[:name]) @user ||= User.create(user_params) + puts ENV if @user.valid? && @user.authenticate(user_params[:password]) + UserMailer.welcome_email(@user).deliver_now session[:user_id] = @user.id redirect_to tasks_path end @@ -20,6 +22,6 @@ def destroy private def user_params - params.require(:user).permit(:name, :password) + params.require(:user).permit(:name, :password, :email) end end diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb index fe8a15d..3aa4e9c 100644 --- a/app/controllers/tasks_controller.rb +++ b/app/controllers/tasks_controller.rb @@ -3,7 +3,12 @@ class TasksController < ApplicationController def index @task = Task.new - @tasks = Task.for_dashboard(params).where(user_id: params[:user_id] || current_user) + @user = User.find_by(id: params[:user_id]) + if @user && JSON.parse(@user.shared).kind_of?(Array) && JSON.parse(@user.shared).include?(current_user.id) + @tasks = Task.for_dashboard(params).where(user_id: @user.id) + else + @tasks = Task.for_dashboard(params).where(user_id: current_user) + end end def create @@ -18,6 +23,18 @@ def update head 200 end + def share + @user = User.find_by(name: share_users_tasks_params[:name]) + if current_user.shared && JSON.parse(current_user.shared).kind_of?(Array) + shared = JSON.parse(current_user.shared) + shared.push(@user.id) + current_user.shared = shared + else + current_user.shared = [@user.id] + end + current_user.save + end + def destroy Task.delete(params[:id]) redirect_to :root @@ -36,4 +53,8 @@ def update_task_params def task_params params.require(:task).permit(:title, :description, :expire_at, :status) end + + def share_users_tasks_params + params.permit(:name) + end end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 286b223..efa6114 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -1,4 +1,4 @@ class ApplicationMailer < ActionMailer::Base - default from: 'from@example.com' + default from: "'Danya' " layout 'mailer' end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb new file mode 100644 index 0000000..9ac5c69 --- /dev/null +++ b/app/mailers/user_mailer.rb @@ -0,0 +1,16 @@ +class UserMailer < ApplicationMailer + default from: "'Danya' " + layout 'mailer' + + def welcome_email(user) + @user = user + @url = 'http://localhost:3000/session/new' + # mail(to: @user.email, subject: 'Welcome to TODO LIST') + mg_client = Mailgun::Client.new ENV['api_key'] + message_params = {:from => ENV['gmail_username'], + :to => @user.email, + :subject => 'Sample Mail using Mailgun API', + :text => 'This mail is sent using Mailgun API via mailgun-ruby'} + mg_client.send_message ENV['domain'], message_params + end +end diff --git a/app/models/task.rb b/app/models/task.rb index 2a43fea..8989f2b 100644 --- a/app/models/task.rb +++ b/app/models/task.rb @@ -1,5 +1,7 @@ class Task < ApplicationRecord - belongs_to :user + # belongs_to :user + has_and_belongs_to_many :users + has_one :owner, :class_name => 'User' validates :title, presence: true validates :description, presence: true @@ -10,6 +12,5 @@ class Task < ApplicationRecord scope :q, ->(q) { where("title LIKE '%#{q}%'") unless q.blank? } scope :status, ->(status) { where(status: status) unless status.blank? } scope :expired, ->(val) { where("expire_at #{val == 'Expired' ? '<' : '>'} ?", Time.now) unless val.blank?} - scope :for_dashboard, ->(params) { q(params[:q]).status(params[:status]).expired(params[:expired]).paginate(page: params[:page], per_page: 5) } - + scope :for_dashboard, ->(params) { q(params[:q]).status(params[:status]).expired(params[:expired]).order('title, expire_at').paginate(page: params[:page], per_page: 5) } end diff --git a/app/models/user.rb b/app/models/user.rb index 30a97a4..30534ec 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,7 @@ class User < ApplicationRecord validates :name, presence: true, uniqueness: true, length: { minimum: 3 } + validates :email, uniqueness: true, length: { minimum: 3 } + validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i validates_length_of :password, minimum: 6, allow_blank: true has_secure_password validations: false diff --git a/app/views/sessions/_form.html.erb b/app/views/sessions/_form.html.erb index 24f8901..68e6d9b 100644 --- a/app/views/sessions/_form.html.erb +++ b/app/views/sessions/_form.html.erb @@ -1,12 +1,16 @@
<%= form_for @user, url: session_path, remote: true, method: :post do |f| %> +
+ <%= f.text_field :email, placeholder: 'Email', class: 'form-control' %> +

<%= @user.errors[:email].first %>

+
<%= f.text_field :name, placeholder: 'Username', class: 'form-control' %> - <%= @user.errors[:name].first %> +

<%= @user.errors[:name].first %>

- <%= f.password_field :password, placeholder: 'Username', class: 'form-control' %> - <%= @user.errors[:password].first %> +
<%= f.password_field :password, placeholder: 'Password', class: 'form-control' %>
+

<%= @user.errors[:name].first %>

<%= f.submit 'Sign Up', class: 'btn btn-primary' %>
<% end %> diff --git a/app/views/tasks/index.html.erb b/app/views/tasks/index.html.erb index bb1bfc5..3b191dd 100644 --- a/app/views/tasks/index.html.erb +++ b/app/views/tasks/index.html.erb @@ -3,10 +3,18 @@ +<%= form_tag '/tasks/share', controller: @user, method: :post, class: 'share-form', remote: true do |f| %> + +<% end %> <%= form_tag tasks_path, method: :get, class: 'search-form', remote: true do |f| %>
- <%= select_tag :status, options_for_select(Task.statuses.keys, params[:status]), prompt: 'All' %> - <%= select_tag :expired, options_for_select(['Expired', 'Feature'], params[:status]), prompt: 'All' %> +
+ <%= select_tag :status, options_for_select(Task.statuses.keys, params[:status]), prompt: 'All' %> + <%= select_tag :expired, options_for_select(['Expired', 'Feature'], params[:status]), prompt: 'All' %> +
diff --git a/app/views/user_mailer/welcome_email.html.erb b/app/views/user_mailer/welcome_email.html.erb new file mode 100644 index 0000000..3a9a550 --- /dev/null +++ b/app/views/user_mailer/welcome_email.html.erb @@ -0,0 +1,17 @@ + + + + + + +

Welcome to TODO LIST, <%= @user.name %>

+

+ You have successfully signed up to TODO LIST. + your username is: <%= @user.name %>.
+

+

+ To login to the site, just follow this link: <%= @url %>. +

+

Thanks for joining and have a great day!

+ + \ No newline at end of file diff --git a/app/views/user_mailer/welcome_email.text.erb b/app/views/user_mailer/welcome_email.text.erb new file mode 100644 index 0000000..388e5aa --- /dev/null +++ b/app/views/user_mailer/welcome_email.text.erb @@ -0,0 +1,9 @@ +Welcome to TODO LIST, <%= @user.name %> +=============================================== + +You have successfully signed up to example.com, +your username is: <%= @user.name %>. + +To login to the site, just follow this link: <%= @url %>. + +Thanks for joining and have a great day! \ No newline at end of file diff --git a/config/application.rb b/config/application.rb index dae5195..996a020 100644 --- a/config/application.rb +++ b/config/application.rb @@ -6,6 +6,9 @@ # you've limited to :test, :development, or :production. Bundler.require(*Rails.groups) +# Load application ENV vars and merge with existing ENV vars. Loaded here so can use values in initializers. +ENV.update YAML.load_file('config/application.yml')[Rails.env] rescue {} + module Lesson4 class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. diff --git a/config/application.yml b/config/application.yml new file mode 100644 index 0000000..125deb7 --- /dev/null +++ b/config/application.yml @@ -0,0 +1,6 @@ +api_key: "" +domain: "" +username: "" +password: "" +gmail_username: '' +gmail_password: '' \ No newline at end of file diff --git a/config/environment.rb b/config/environment.rb index 426333b..3fd7635 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -3,3 +3,13 @@ # Initialize the Rails application. Rails.application.initialize! + +ActionMailer::Base.smtp_settings = { + :user_name => 'Daniil', + :password => '1234qwerasdf', + :domain => 'todolistrandom.com', + :address => 'smtp.sendgrid.net', + :port => 587, + :authentication => :plain, + :enable_starttls_auto => true +} \ No newline at end of file diff --git a/config/environments/development.rb b/config/environments/development.rb index 1311e3e..2f9c6ed 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -31,7 +31,18 @@ config.active_storage.service = :local # Don't care if the mailer can't send. - config.action_mailer.raise_delivery_errors = false + # config.action_mailer.raise_delivery_errors = true + config.action_mailer.raise_delivery_errors = true + config.action_mailer.default_url_options = { host: "localhost:3000" } + config.action_mailer.delivery_method = :smtp + config.action_mailer.smtp_settings = { + :port => 587, + :address => "smtp.mailgun.org", + :domain => ENV['domain'], + :user_name => ENV['username'], + :password => ENV['password'], + :authentication => :plain, + } config.action_mailer.perform_caching = false diff --git a/config/environments/production.rb b/config/environments/production.rb index 7506e2c..7c2c8a4 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -65,6 +65,17 @@ config.action_mailer.perform_caching = false + # config.action_mailer.delivery_method = :smtp + # # SMTP settings for gmail + # config.action_mailer.smtp_settings = { + # :address => "smtp.gmail.com", + # :port => 587, + # :user_name => ENV['gmail_username'], + # :password => ENV['gmail_password'], + # :authentication => "plain", + # :enable_starttls_auto => true + # } + # Ignore bad email addresses and do not raise email delivery errors. # Set this to true and configure the email server for immediate delivery to raise delivery errors. # config.action_mailer.raise_delivery_errors = false diff --git a/config/locales/en.yml b/config/locales/en.yml index 407cd6e..62a5863 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3,4 +3,4 @@ en: search: 'Search' tasks: index: - search: 'SDASDa' + search: 'Search' diff --git a/config/routes.rb b/config/routes.rb index 06ae911..2dd0de4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,6 +2,7 @@ get 'users', to: 'users#index' get 'users/login', to: 'users#login' post 'users/login', to: 'users#create' + post 'tasks/share', to: 'tasks#share' get 'users/registration', to: 'users#registration' get 'index', to: 'welcome#index' root 'tasks#index' diff --git a/db/migrate/20181110170834_create_users.rb b/db/migrate/20181110170834_create_users.rb index e7073ec..a139a52 100644 --- a/db/migrate/20181110170834_create_users.rb +++ b/db/migrate/20181110170834_create_users.rb @@ -3,7 +3,8 @@ def change create_table :users do |t| t.string :name t.string :password_digest - # t.array :tasks + t.string :email + t.string :shared, array: true t.timestamps end diff --git a/db/schema.rb b/db/schema.rb index ae69849..94aed6c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -26,6 +26,8 @@ create_table "users", force: :cascade do |t| t.string "name" t.string "password_digest" + t.string "email" + t.string "shared" t.datetime "created_at", null: false t.datetime "updated_at", null: false end diff --git a/test/mailers/previews/user_mailer_preview.rb b/test/mailers/previews/user_mailer_preview.rb new file mode 100644 index 0000000..957e12b --- /dev/null +++ b/test/mailers/previews/user_mailer_preview.rb @@ -0,0 +1,4 @@ +# Preview all emails at http://localhost:3000/rails/mailers/user_mailer +class UserMailerPreview < ActionMailer::Preview + +end diff --git a/test/mailers/user_mailer_test.rb b/test/mailers/user_mailer_test.rb new file mode 100644 index 0000000..67a1629 --- /dev/null +++ b/test/mailers/user_mailer_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class UserMailerTest < ActionMailer::TestCase + # test "the truth" do + # assert true + # end +end From 1f62f876935ec4976d5d2c7ef7f40c49e9d4a1b9 Mon Sep 17 00:00:00 2001 From: Yarmolenko Daniil Date: Sun, 25 Nov 2018 15:39:21 +0200 Subject: [PATCH 2/2] code refactoring --- app/controllers/sessions_controller.rb | 1 - app/controllers/tasks_controller.rb | 7 ++++--- app/mailers/user_mailer.rb | 14 +++++++------- config/environment.rb | 12 +----------- 4 files changed, 12 insertions(+), 22 deletions(-) diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 019d55e..f93ce40 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -7,7 +7,6 @@ def new def create @user = User.find_by(name: user_params[:name]) @user ||= User.create(user_params) - puts ENV if @user.valid? && @user.authenticate(user_params[:password]) UserMailer.welcome_email(@user).deliver_now session[:user_id] = @user.id diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb index 3aa4e9c..560b9c6 100644 --- a/app/controllers/tasks_controller.rb +++ b/app/controllers/tasks_controller.rb @@ -4,7 +4,8 @@ class TasksController < ApplicationController def index @task = Task.new @user = User.find_by(id: params[:user_id]) - if @user && JSON.parse(@user.shared).kind_of?(Array) && JSON.parse(@user.shared).include?(current_user.id) + shared = @user && JSON.parse(@user.shared) + if shared.kind_of?(Array) && shared.include?(current_user.id) @tasks = Task.for_dashboard(params).where(user_id: @user.id) else @tasks = Task.for_dashboard(params).where(user_id: current_user) @@ -25,8 +26,8 @@ def update def share @user = User.find_by(name: share_users_tasks_params[:name]) - if current_user.shared && JSON.parse(current_user.shared).kind_of?(Array) - shared = JSON.parse(current_user.shared) + shared = current_user.shared && JSON.parse(current_user.shared) + if shared.kind_of?(Array) shared.push(@user.id) current_user.shared = shared else diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 9ac5c69..d4b20a9 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -5,12 +5,12 @@ class UserMailer < ApplicationMailer def welcome_email(user) @user = user @url = 'http://localhost:3000/session/new' - # mail(to: @user.email, subject: 'Welcome to TODO LIST') - mg_client = Mailgun::Client.new ENV['api_key'] - message_params = {:from => ENV['gmail_username'], - :to => @user.email, - :subject => 'Sample Mail using Mailgun API', - :text => 'This mail is sent using Mailgun API via mailgun-ruby'} - mg_client.send_message ENV['domain'], message_params + mail(to: @user.email, subject: 'Welcome to TODO LIST') + # mg_client = Mailgun::Client.new ENV['api_key'] + # message_params = {:from => ENV['gmail_username'], + # :to => @user.email, + # :subject => 'Sample Mail using Mailgun API', + # :text => 'This mail is sent using Mailgun API via mailgun-ruby'} + # mg_client.send_message ENV['domain'], message_params end end diff --git a/config/environment.rb b/config/environment.rb index 3fd7635..856fba2 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -2,14 +2,4 @@ require_relative 'application' # Initialize the Rails application. -Rails.application.initialize! - -ActionMailer::Base.smtp_settings = { - :user_name => 'Daniil', - :password => '1234qwerasdf', - :domain => 'todolistrandom.com', - :address => 'smtp.sendgrid.net', - :port => 587, - :authentication => :plain, - :enable_starttls_auto => true -} \ No newline at end of file +Rails.application.initialize! \ No newline at end of file