diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..9b0b0ed Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index 5b61ab0..2784374 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ # Ignore bundler config. /.bundle +/config/initializers/app_vars.rb + # Ignore all logfiles and tempfiles. /log/* !/log/.keep diff --git a/Gemfile b/Gemfile index bd345bb..0efb57d 100644 --- a/Gemfile +++ b/Gemfile @@ -1,46 +1,37 @@ source 'https://rubygems.org' - - -# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '4.2.1' -# Use postgresql as the database for Active Record gem 'pg' -# Use SCSS for stylesheets gem 'sass-rails', '~> 5.0' -# Use Uglifier as compressor for JavaScript assets gem 'uglifier', '>= 1.3.0' -# Use CoffeeScript for .coffee assets and views gem 'coffee-rails', '~> 4.1.0' -# See https://github.com/rails/execjs#readme for more supported runtimes -# gem 'therubyracer', platforms: :ruby - -# Use jquery as the JavaScript library gem 'jquery-rails' -# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks gem 'turbolinks' -# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 2.0' -# bundle exec rake doc:rails generates the API under doc/api. gem 'sdoc', '~> 0.4.0', group: :doc - -# Use ActiveModel has_secure_password -# gem 'bcrypt', '~> 3.1.7' - +gem 'bcrypt', '~> 3.1.7' +gem 'delayed_job_active_record' +gem "delayed_job_web" +gem 'bootstrap-sass' +gem 'bootstrap-kaminari-views' +gem 'cancancan' +gem 'whenever', :require => false +gem 'carrierwave' +gem "mini_magick" + + +# , :group => :development # Use Unicorn as the app server # gem 'unicorn' - # Use Capistrano for deployment # gem 'capistrano-rails', group: :development - group :development, :test do - # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug' gem "hirb" gem "awesome_print" gem "interactive_editor" - # Access an IRB console on exception pages or by using <%= console %> in views gem 'web-console', '~> 2.0' - - # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring + gem "letter_opener" gem 'spring' + gem "faker" + gem "rails-erd" end diff --git a/Gemfile.lock b/Gemfile.lock index 50157f9..82a883e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -36,13 +36,32 @@ GEM minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) + addressable (2.3.8) arel (6.0.0) + autoprefixer-rails (5.2.0) + execjs + json awesome_print (1.6.1) + bcrypt (3.1.10) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) + bootstrap-kaminari-views (0.0.5) + kaminari (>= 0.13) + rails (>= 3.1) + bootstrap-sass (3.3.4.1) + autoprefixer-rails (>= 5.0.0.1) + sass (>= 3.2.19) builder (3.2.2) byebug (5.0.0) columnize (= 0.9.0) + cancancan (1.10.1) + carrierwave (0.10.0) + activemodel (>= 3.2.0) + activesupport (>= 3.2.0) + json (>= 1.7) + mime-types (>= 1.16) + choice (0.2.0) + chronic (0.10.2) coffee-rails (4.1.0) coffee-script (>= 2.2.0) railties (>= 4.0.0, < 5.0) @@ -52,8 +71,19 @@ GEM coffee-script-source (1.9.1.1) columnize (0.9.0) debug_inspector (0.0.2) + delayed_job (4.0.6) + activesupport (>= 3.0, < 5.0) + delayed_job_active_record (4.0.3) + activerecord (>= 3.0, < 5.0) + delayed_job (>= 3.0, < 4.1) + delayed_job_web (1.2.10) + activerecord (> 3.0.0) + delayed_job (> 2.0.3) + sinatra (>= 1.4.4) erubis (2.7.0) execjs (2.5.2) + faker (1.4.3) + i18n (~> 0.5) ffi (1.9.8) globalid (0.3.5) activesupport (>= 4.1.0) @@ -69,11 +99,19 @@ GEM railties (>= 4.2.0) thor (>= 0.14, < 2.0) json (1.8.3) + kaminari (0.16.3) + actionpack (>= 3.0.0) + activesupport (>= 3.0.0) + launchy (2.4.3) + addressable (~> 2.3) + letter_opener (1.4.1) + launchy (~> 2.2) loofah (2.0.2) nokogiri (>= 1.5.9) mail (2.6.3) mime-types (>= 1.16, < 3) mime-types (2.6.1) + mini_magick (4.2.7) mini_portile (0.6.2) minitest (5.7.0) multi_json (1.11.0) @@ -81,6 +119,8 @@ GEM mini_portile (~> 0.6.0) pg (0.18.2) rack (1.6.1) + rack-protection (1.5.3) + rack rack-test (0.6.3) rack (>= 1.0) rails (4.2.1) @@ -100,6 +140,11 @@ GEM activesupport (>= 4.2.0.beta, < 5.0) nokogiri (~> 1.6.0) rails-deprecated_sanitizer (>= 1.0.1) + rails-erd (1.4.0) + activerecord (>= 3.2) + activesupport (>= 3.2) + choice (~> 0.2.0) + ruby-graphviz (~> 1.2) rails-html-sanitizer (1.0.2) loofah (~> 2.0) railties (4.2.1) @@ -109,6 +154,7 @@ GEM thor (>= 0.18.1, < 2.0) rake (10.4.2) rdoc (4.2.0) + ruby-graphviz (1.2.2) sass (3.4.14) sass-rails (5.0.3) railties (>= 4.0.0, < 5.0) @@ -119,6 +165,10 @@ GEM sdoc (0.4.1) json (~> 1.7, >= 1.7.7) rdoc (~> 4.0) + sinatra (1.4.6) + rack (~> 1.4) + rack-protection (~> 1.4) + tilt (>= 1.3, < 3) spoon (0.0.4) ffi spring (1.3.6) @@ -143,26 +193,40 @@ GEM binding_of_caller (>= 0.7.2) railties (>= 4.0) sprockets-rails (>= 2.0, < 4.0) + whenever (0.9.4) + chronic (>= 0.6.3) PLATFORMS ruby DEPENDENCIES awesome_print + bcrypt (~> 3.1.7) + bootstrap-kaminari-views + bootstrap-sass byebug + cancancan + carrierwave coffee-rails (~> 4.1.0) + delayed_job_active_record + delayed_job_web + faker hirb interactive_editor jbuilder (~> 2.0) jquery-rails + letter_opener + mini_magick pg rails (= 4.2.1) + rails-erd sass-rails (~> 5.0) sdoc (~> 0.4.0) spring turbolinks uglifier (>= 1.3.0) web-console (~> 2.0) + whenever BUNDLED WITH 1.10.2 diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index e07c5a8..1662961 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -13,4 +13,5 @@ //= require jquery //= require jquery_ujs //= require turbolinks +//= require bootstrap //= require_tree . diff --git a/app/assets/javascripts/comments.coffee b/app/assets/javascripts/comments.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/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/favourites.coffee b/app/assets/javascripts/favourites.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/favourites.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/posts.coffee b/app/assets/javascripts/posts.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/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/sessions.coffee b/app/assets/javascripts/sessions.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/sessions.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/users.coffee b/app/assets/javascripts/users.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/users.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/bootstrap_and_overrides.scss b/app/assets/stylesheets/bootstrap_and_overrides.scss new file mode 100644 index 0000000..baccee2 --- /dev/null +++ b/app/assets/stylesheets/bootstrap_and_overrides.scss @@ -0,0 +1,2 @@ +@import "bootstrap-sprockets"; +@import "bootstrap"; diff --git a/app/assets/stylesheets/comments.scss b/app/assets/stylesheets/comments.scss new file mode 100644 index 0000000..3722c12 --- /dev/null +++ b/app/assets/stylesheets/comments.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the 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/favourites.scss b/app/assets/stylesheets/favourites.scss new file mode 100644 index 0000000..66cc292 --- /dev/null +++ b/app/assets/stylesheets/favourites.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the favourites 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/posts.scss b/app/assets/stylesheets/posts.scss new file mode 100644 index 0000000..1a7e153 --- /dev/null +++ b/app/assets/stylesheets/posts.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the 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/sessions.scss b/app/assets/stylesheets/sessions.scss new file mode 100644 index 0000000..7bef9cf --- /dev/null +++ b/app/assets/stylesheets/sessions.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the sessions 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/users.scss b/app/assets/stylesheets/users.scss new file mode 100644 index 0000000..1efc835 --- /dev/null +++ b/app/assets/stylesheets/users.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the users 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/application_controller.rb b/app/controllers/application_controller.rb index d83690e..d8ab139 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -2,4 +2,21 @@ class ApplicationController < ActionController::Base # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception + + def authenticate_user! + redirect_to new_session_path, notice: "Please sign in" unless user_signed_in? + end + + def user_signed_in? + current_user.present? + end + + helper_method :user_signed_in? + + def current_user + @current_user ||= User.find_by_id(session[:user_id]) + end + + helper_method :current_user + end diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb new file mode 100644 index 0000000..9711c40 --- /dev/null +++ b/app/controllers/comments_controller.rb @@ -0,0 +1,58 @@ +class CommentsController < ApplicationController + + before_action :authenticate_user! + + def create + comment_params = params.require(:comment).permit(:body) + @post = Post.find(params[:post_id]) + @comment = Comment.new comment_params + @comment.post_id = params[:post_id] + @comment.user = current_user + respond_to do |format| + if @comment.save + # PostsMailer.notify_post_owner(@comment).deliver_now + PostsMailer.delay.notify_post_owner(@comment) + format.js { render } + format.html { redirect_to post_path(@post) } + else + @comments = Comment.search(@post.id) + format.js { render :create_failure } + format.html { render "/posts/show" } + end + end + end + + def edit + @comment = Comment.find params[:id] + @post = Post.find params[:post_id] + end + + def update + @post = Post.find params[:post_id] + comment_params = params.require(:comment).permit(:body) + @comment = Comment.find params[:id] + respond_to do |format| + if @comment.update comment_params + format.js { render :update } + format.html {redirect_to post_path(@post)} + else + format.js { render } + format.html {render :edit, notice: "Failed to update."} + end + end + end + + def destroy + post = Post.find params[:post_id] + @comment = Comment.find params[:id] + @comment.destroy + respond_to do |format| + format.js { render } + format.html { + flash[:notice] = "Comment successfully deleted \n\n" + redirect_to post + } + end + end + +end diff --git a/app/controllers/favourites_controller.rb b/app/controllers/favourites_controller.rb new file mode 100644 index 0000000..75964a2 --- /dev/null +++ b/app/controllers/favourites_controller.rb @@ -0,0 +1,28 @@ +class FavouritesController < ApplicationController + + + before_action :authenticate_user! + + def create + post = Post.find params[:post_id] + favourite = post.favourites.new + favourite.user = current_user + if favourite.save + redirect_to post, notice: "Post favourited" + else + redirect_to post, alert: "Error!" + end + end + + def destroy + post = Post.find params[:post_id] + favourite = current_user.favourites.find_by_post_id(post) + favourite.destroy + redirect_to post, notice: "Un-favourited" + end + + def index + @favourites = current_user.favourites + end + +end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb new file mode 100644 index 0000000..8f4f81d --- /dev/null +++ b/app/controllers/posts_controller.rb @@ -0,0 +1,54 @@ +class PostsController < ApplicationController + + before_action :authenticate_user!, except: [:index, :show] + + def index + @posts = Post.all + end + + def new + @post = Post.new + end + + def create + post_params = params.require(:post).permit(:asset, :title, :body, {tag_ids: []}) + @post = Post.new post_params + @post.user = current_user + if @post.save + redirect_to posts_path + else + flash[:alert] = "Post failed to create. Please correct errors." + render :new + end + end + + def show + @post = Post.find params[:id] + @comment = Comment.new + @comments = Comment.search(@post.id) + @favourite = @post.favourite_for(current_user) + end + + def destroy + @post = Post.find params[:id] + @post.destroy + flash[:notice] = "Successfully deleted post!" + redirect_to posts_path + end + + def edit + @post = Post.find params[:id] + end + + def update + @post = Post.find params[:id] + post_params = params.require(:post).permit(:asset, :title, :body, {tag_ids: []}) + if @post.update post_params + flash[:notice] = "Successfully updated post!" + redirect_to posts_path + else + flash[:alert] = "Post failed to create." + render :edit + end + end +end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 0000000..7976855 --- /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 && @user.authenticate(params[:password]) + session[:user_id] = @user.id + redirect_to root_path, notice: "Logged in" + else + flash[:alert] = "Wrong email or password" + render :new + end + end + + def destroy + session[:user_id] = nil + redirect_to root_path, notice: "Logged out" + end + +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100644 index 0000000..e4ccd3b --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,39 @@ +class UsersController < ApplicationController + + before_action :authenticate_user!, only: [:update] + + def new + @user = User.new + end + + def create + user_params = params.require(:user).permit(:first_name, :last_name, :email, + :password, :password_confirmation) + @user = User.new user_params + if @user.save + session[:user_id] = @user.id + redirect_to root_path, notice: "Logged In!" + else + render :new + end + end + + def edit + @user = current_user + end + + def update + user_params = params.require(:user).permit(:first_name, :last_name, :email, + :password, :password_confirmation) + @user = current_user + if !@user.authenticate(params[:user][:current_password]) + flash[:alert] = "You've entered the wrong password" + render :edit + elsif @user.update(user_params) + redirect_to edit_users_path, notice: "Information updated" + else + render :edit + end + end + +end diff --git a/app/helpers/comments_helper.rb b/app/helpers/comments_helper.rb new file mode 100644 index 0000000..0ec9ca5 --- /dev/null +++ b/app/helpers/comments_helper.rb @@ -0,0 +1,2 @@ +module CommentsHelper +end diff --git a/app/helpers/favourites_helper.rb b/app/helpers/favourites_helper.rb new file mode 100644 index 0000000..907962e --- /dev/null +++ b/app/helpers/favourites_helper.rb @@ -0,0 +1,2 @@ +module FavouritesHelper +end diff --git a/app/helpers/posts_helper.rb b/app/helpers/posts_helper.rb new file mode 100644 index 0000000..a7b8cec --- /dev/null +++ b/app/helpers/posts_helper.rb @@ -0,0 +1,2 @@ +module PostsHelper +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/mailers/application_mailer.rb b/app/mailers/application_mailer.rb new file mode 100644 index 0000000..d25d889 --- /dev/null +++ b/app/mailers/application_mailer.rb @@ -0,0 +1,4 @@ +class ApplicationMailer < ActionMailer::Base + default from: "from@example.com" + layout 'mailer' +end diff --git a/app/mailers/posts_mailer.rb b/app/mailers/posts_mailer.rb new file mode 100644 index 0000000..e58a140 --- /dev/null +++ b/app/mailers/posts_mailer.rb @@ -0,0 +1,15 @@ +class PostsMailer < ApplicationMailer + + def notify_post_owner (comment) + @comment = comment + @user = @comment.post.user + mail(to: @user.email, subject: "Someone commented on your post") + end + + def notify_post_owners_summary clustered_array + clustered_array.each_with_index do |cluster, i| + @cluster = cluster + mail(to: @cluster[0].post.user.email, subject: "Comments in the last 24 hours") + end + end +end diff --git a/app/models/category.rb b/app/models/category.rb index 910a009..0d71b56 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -1,2 +1,7 @@ class Category < ActiveRecord::Base + + has_many :posts, dependent: :nullify + + validates :title, presence: true + end diff --git a/app/models/comment.rb b/app/models/comment.rb index 45b2d38..b5a8192 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -1,2 +1,13 @@ class Comment < ActiveRecord::Base + + + validates :body, presence: true, uniqueness: { scope: :post_id } + + belongs_to :post + belongs_to :user + + def self.search id + Comment.where("post_id = #{id}").order("created_at desc") + end + end diff --git a/app/models/contact.rb b/app/models/contact.rb deleted file mode 100644 index a5ee858..0000000 --- a/app/models/contact.rb +++ /dev/null @@ -1,2 +0,0 @@ -class Contact < ActiveRecord::Base -end diff --git a/app/models/favourite.rb b/app/models/favourite.rb new file mode 100644 index 0000000..2ce9cc0 --- /dev/null +++ b/app/models/favourite.rb @@ -0,0 +1,6 @@ +class Favourite < ActiveRecord::Base + belongs_to :user + belongs_to :post + + validates :user_id, uniqueness: {scope: :post_id} +end diff --git a/app/models/post.rb b/app/models/post.rb new file mode 100644 index 0000000..d52ee22 --- /dev/null +++ b/app/models/post.rb @@ -0,0 +1,23 @@ +class Post < ActiveRecord::Base + + mount_uploader :asset, AssetUploader + + has_many :taggings, dependent: :destroy + has_many :tags, through: :taggings + + has_many :favourites, dependent: :destroy + has_many :favouriting_users, through: :favourites, source: :user + + belongs_to :user + belongs_to :category + has_many :comments, dependent: :destroy + validates :title, presence: true, uniqueness: true + + def favourited_by?(user) + favourites.where(user: user).present? + end + + def favourite_for(user) + favourites.find_by_user_id(user) + end +end diff --git a/app/models/post_file.rb b/app/models/post_file.rb new file mode 100644 index 0000000..1740810 --- /dev/null +++ b/app/models/post_file.rb @@ -0,0 +1,3 @@ +class PostFile < ActiveRecord::Base + belongs_to :post +end diff --git a/app/models/tag.rb b/app/models/tag.rb new file mode 100644 index 0000000..b9bd168 --- /dev/null +++ b/app/models/tag.rb @@ -0,0 +1,8 @@ +class Tag < ActiveRecord::Base + + has_many :taggings, dependent: :destroy + has_many :posts, through: :taggings + + validates :name, uniqueness: true + +end diff --git a/app/models/tagging.rb b/app/models/tagging.rb new file mode 100644 index 0000000..1c1cbfd --- /dev/null +++ b/app/models/tagging.rb @@ -0,0 +1,6 @@ +class Tagging < ActiveRecord::Base + belongs_to :tag + belongs_to :post + + validates :tag_id, uniqueness: {scope: :post_id} +end diff --git a/app/models/title.rb b/app/models/title.rb deleted file mode 100644 index bee2c4c..0000000 --- a/app/models/title.rb +++ /dev/null @@ -1,2 +0,0 @@ -class Title < ActiveRecord::Base -end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000..b32fcc1 --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,15 @@ +class User < ActiveRecord::Base + + has_many :favourites, dependent: :destroy + has_many :favourited_posts, through: :favourites, source: :post + + has_many :posts, dependent: :destroy + has_many :comments, dependent: :destroy + has_secure_password + validates :email, presence: :true, uniqueness: true, + format: /\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i + + def full_name + "#{first_name} #{last_name}".strip.squeeze(" ") + end +end diff --git a/app/uploaders/asset_uploader.rb b/app/uploaders/asset_uploader.rb new file mode 100644 index 0000000..ec7137f --- /dev/null +++ b/app/uploaders/asset_uploader.rb @@ -0,0 +1,51 @@ +# encoding: utf-8 + +class AssetUploader < CarrierWave::Uploader::Base + + # Include RMagick or MiniMagick support: + # include CarrierWave::RMagick + # include CarrierWave::MiniMagick + + # Choose what kind of storage to use for this uploader: + storage :file + # storage :fog + + # Override the directory where uploaded files will be stored. + # This is a sensible default for uploaders that are meant to be mounted: + def store_dir + "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" + end + + # Provide a default URL as a default if there hasn't been a file uploaded: + # def default_url + # # For Rails 3.1+ asset pipeline compatibility: + # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_')) + # + # "/images/fallback/" + [version_name, "default.png"].compact.join('_') + # end + + # Process files as they are uploaded: + # process :scale => [200, 300] + # + # def scale(width, height) + # # do something + # end + + # Create different versions of your uploaded files: + # version :thumb do + # process :resize_to_fit => [50, 50] + # end + + #Add a white list of extensions which are allowed to be uploaded. + # For images you might use something like this: + #def extension_white_list + # %w(jpg jpeg gif png) + #end + + # Override the filename of the uploaded files: + # Avoid using model.id or version_name here, see uploader/store.rb for details. + # def filename + # "something.jpg" if original_filename + # end + +end diff --git a/app/views/comments/_comment.html.erb b/app/views/comments/_comment.html.erb new file mode 100644 index 0000000..617d81c --- /dev/null +++ b/app/views/comments/_comment.html.erb @@ -0,0 +1,13 @@ +
+ +

+ <%= User.find_by_id(comment.user_id).full_name %>: <%= comment.body %> + <%= link_to "Edit", edit_post_comment_path(@post,comment), remote: true %> + <%= link_to "Delete", post_comment_path(@post, comment), method: :delete, + data: {confirm: "Delete comment?"}, remote: true %>
+ commented at <%= comment.created_at %>: +

+
+ + +
diff --git a/app/views/comments/_form.html.erb b/app/views/comments/_form.html.erb new file mode 100644 index 0000000..d14c3af --- /dev/null +++ b/app/views/comments/_form.html.erb @@ -0,0 +1,23 @@ +<%= form_for [@post, @comment], html: {class: "form-horizontal"}, remote: true do |f| %> +
+
+ <%= f.label :body %> +
+ + <%= f.text_area :body, html: {class: "form-control"}, :cols => 100, :rows => 5 %> +
+ <%= f.submit class: "btn btn-primary" %> + + +

+ + <% if @comment.errors.any? %> + <% @comment.errors.full_messages.each do |msg| %> + <%= msg %>
+ <% end %> + <% end %> +
+ +
+ +<% end %> diff --git a/app/views/comments/create.js.erb b/app/views/comments/create.js.erb new file mode 100644 index 0000000..9b76c9d --- /dev/null +++ b/app/views/comments/create.js.erb @@ -0,0 +1,4 @@ +$('#comment_box').prepend("<%= j render 'comment', comment: @comment %>") + +<% @comment = Comment.new %> +$('#new_comment').replaceWith("<%= j render 'form' %>") diff --git a/app/views/comments/create_failure.js.erb b/app/views/comments/create_failure.js.erb new file mode 100644 index 0000000..8b5725d --- /dev/null +++ b/app/views/comments/create_failure.js.erb @@ -0,0 +1 @@ +$('#new_comment').replaceWith(" <%= j render 'form' %>"); diff --git a/app/views/comments/destroy.js.erb b/app/views/comments/destroy.js.erb new file mode 100644 index 0000000..14901e6 --- /dev/null +++ b/app/views/comments/destroy.js.erb @@ -0,0 +1 @@ +$("#<%= dom_id(@comment) %>").fadeOut() diff --git a/app/views/comments/edit.html.erb b/app/views/comments/edit.html.erb new file mode 100644 index 0000000..9479e54 --- /dev/null +++ b/app/views/comments/edit.html.erb @@ -0,0 +1,2 @@ +

Edit the Comment

+<%= render 'form' %> diff --git a/app/views/comments/edit.js.erb b/app/views/comments/edit.js.erb new file mode 100644 index 0000000..c32dbc6 --- /dev/null +++ b/app/views/comments/edit.js.erb @@ -0,0 +1,4 @@ +$('#<%= dom_id(@comment) %>').fadeOut() +setTimeout(function() { + $("#<%= dom_id(@comment) %>").replaceWith("<%= j render 'form' %>") +},300) diff --git a/app/views/comments/update.js.erb b/app/views/comments/update.js.erb new file mode 100644 index 0000000..9e41c38 --- /dev/null +++ b/app/views/comments/update.js.erb @@ -0,0 +1,4 @@ +$('#<%= dom_id(@comment, :edit) %>').fadeOut() +setTimeout(function() { + $('#<%= dom_id(@comment, :edit) %>').replaceWith("<%= j render 'comment', comment: @comment %>") +},300) diff --git a/app/views/favourites/index.html.erb b/app/views/favourites/index.html.erb new file mode 100644 index 0000000..90f7863 --- /dev/null +++ b/app/views/favourites/index.html.erb @@ -0,0 +1,8 @@ +

Your Favourite Posts

+ + +<% @favourites.each do |favourite| %> + +

<%= link_to "#{favourite.post.title}", favourite.post %>

+ +<% end %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 4191809..0a8c30d 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -1,16 +1,37 @@ - Quiz1 + Murphy's Blog <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> <%= csrf_meta_tags %> -<%= link_to "Home", root_path %> | -<%= link_to "All Requests", requests_path %> | -<%= link_to "Add a Request", new_request_path %> -<%= yield %> +
+ <%= link_to "Home", root_path %> | + <%= link_to "About Me", home_about_path %> | + <%= link_to "All Posts", posts_path %> | + <%= link_to "Add a Post", new_post_path %> | + <% unless user_signed_in? %> + <%= link_to "Sign up", new_user_path %> | + <%= link_to "Login", new_session_path %> + + <% end %> + <% if user_signed_in? %> + <%= link_to "Edit Profile", edit_users_path %> | + <%= link_to "Logout", sessions_path, method: :delete %> | + Hi there <%= current_user.full_name %>, here are your <%= current_user.favourites.length %> + <%= link_to 'Favourite Posts', user_favourites_path(current_user) %> + + <% end %> + <% if flash[:alert] %> +

<%= flash[:alert] %>
+ <% end %> + <% if flash[:notice] %> +

<%= flash[:notice] %>
+ <% end %> + <%= yield %> +
diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb new file mode 100644 index 0000000..991cf0f --- /dev/null +++ b/app/views/layouts/mailer.html.erb @@ -0,0 +1,5 @@ + + + <%= yield %> + + diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb new file mode 100644 index 0000000..37f0bdd --- /dev/null +++ b/app/views/layouts/mailer.text.erb @@ -0,0 +1 @@ +<%= yield %> diff --git a/app/views/posts/_form.html.erb b/app/views/posts/_form.html.erb new file mode 100644 index 0000000..dc824b1 --- /dev/null +++ b/app/views/posts/_form.html.erb @@ -0,0 +1,27 @@ +<% if @post.errors.any? %> + +<% end %> + +<%= form_for @post do |f| %> +
+ <%= f.label :title %> + <%= f.text_field :title %> +
+
+ <%= f.label :asset %> + <%= f.file_field :asset %> +
+
+ <%= f.label :body %> + <%= f.text_area :body %> +
+
+
+ <%= f.collection_check_boxes :tag_ids, Tag.all, :id, :name %> +
+ <%= f.submit "Submit" %> +<% end %> diff --git a/app/views/posts/edit.html.erb b/app/views/posts/edit.html.erb new file mode 100644 index 0000000..fdadb73 --- /dev/null +++ b/app/views/posts/edit.html.erb @@ -0,0 +1,5 @@ +

Edit this post to suit your needs!

+ +<%= flash.alert %> + +<%= render "form" %> diff --git a/app/views/posts/index.html.erb b/app/views/posts/index.html.erb new file mode 100644 index 0000000..0ffd541 --- /dev/null +++ b/app/views/posts/index.html.erb @@ -0,0 +1,11 @@ +

All Posts

+ +<%= flash.notice %> + +<% @posts.each do |post| %> +
+

<%= link_to post.title, post_path(post) %>

+ + + +<% end %> diff --git a/app/views/posts/new.html.erb b/app/views/posts/new.html.erb new file mode 100644 index 0000000..2700c33 --- /dev/null +++ b/app/views/posts/new.html.erb @@ -0,0 +1,3 @@ +

Create a New Post!

+ +<%= render "form" %> diff --git a/app/views/posts/show.html.erb b/app/views/posts/show.html.erb new file mode 100644 index 0000000..aecd5cc --- /dev/null +++ b/app/views/posts/show.html.erb @@ -0,0 +1,32 @@ + + +

<%= @post.title %>

+ +

<%= @post.body %>

+<% if current_user.present? %> + <% if @post.favourited_by?(current_user) %> + <%= link_to "Un-Favourite", post_favourite_path(@post, @favourite), + method: :delete %> + <% else %> + <%= link_to "Favourite", post_favourites_path(@post), method: :post %> + <% end %> + <%= link_to "Edit", edit_post_path(@post) %> + <%= link_to "Delete", post_path(@post), method: :delete, remote: true, + data: { confirm: "Are you sure you want to delete this?" } %> +<% end %> + + +<%= render "/comments/form" %> + +
+<%# @post.comments.sort_by {|comment| comment.id }.reverse.each_with_index do |comment,i| %> +<% @comments.each_with_index do |comment,i| %> + + <%= render "/comments/comment", comment: comment %> + +<% end %> + +<%= flash[:notice] if flash[:notice] %> + + +
diff --git a/app/views/posts_mailer/notify_post_owner.html.erb b/app/views/posts_mailer/notify_post_owner.html.erb new file mode 100644 index 0000000..f96f146 --- /dev/null +++ b/app/views/posts_mailer/notify_post_owner.html.erb @@ -0,0 +1,2 @@ +Hey <%= @user.full_name %>! Someone commented, "<%= @comment.body %>" on your +post titled <%= @comment.post.title %>. diff --git a/app/views/posts_mailer/notify_post_owners_summary.html.erb b/app/views/posts_mailer/notify_post_owners_summary.html.erb new file mode 100644 index 0000000..8c38993 --- /dev/null +++ b/app/views/posts_mailer/notify_post_owners_summary.html.erb @@ -0,0 +1,7 @@ +Here are the comments made in the last 24 hours, <%= @cluster[0].post.user.full_name %> + +<% @cluster.each do |comment| %> +
+ <%= comment.user.full_name %> said: <%= comment.body %> +
+<% end %> diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb new file mode 100644 index 0000000..bd48717 --- /dev/null +++ b/app/views/sessions/new.html.erb @@ -0,0 +1,15 @@ +

Sign in!

+ +<%= form_tag sessions_path do %> + +
+ <%= label_tag :email %> + <%= text_field_tag :email %> +
+
+ <%= label_tag :password %> + <%= password_field_tag :password %> +
+ <%= submit_tag %> + +<% end %> diff --git a/app/views/users/_form.html.erb b/app/views/users/_form.html.erb new file mode 100644 index 0000000..457fca2 --- /dev/null +++ b/app/views/users/_form.html.erb @@ -0,0 +1,43 @@ +<% if @user.errors.any? %> + +<% end %> + + +<%= form_for @user, url: users_path do |f| %> + +
+ <%= f.label :first_name %> + <%= f.text_field :first_name %> +
+
+ <%= f.label :last_name %> + <%= f.text_field :last_name %> +
+
+ <%= f.label :email %> + <%= f.email_field :email %> +
+ <% if @user.persisted? %> +
+

Please enter your current password to implement changes

+ <%= f.label :current_password %> + <%= f.password_field :current_password %> +
+ <% end %> +
+ <%= f.label :password %> + <%= f.password_field :password %> +
+
+ <%= f.label :password_confirmation %> + <%= f.password_field :password_confirmation %> +
+ + <%= f.submit %> +<% end %> diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb new file mode 100644 index 0000000..e7cae8c --- /dev/null +++ b/app/views/users/edit.html.erb @@ -0,0 +1,3 @@ +

Change your profile

+ +<%= render "form" %> diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb new file mode 100644 index 0000000..f07da2d --- /dev/null +++ b/app/views/users/new.html.erb @@ -0,0 +1,3 @@ +

Create a new User

+ +<%= render "form" %> diff --git a/bin/delayed_job b/bin/delayed_job new file mode 100755 index 0000000..edf1959 --- /dev/null +++ b/bin/delayed_job @@ -0,0 +1,5 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) +require 'delayed/command' +Delayed::Command.new(ARGV).daemonize diff --git a/config/application.rb b/config/application.rb index ecd54d7..de85bd8 100644 --- a/config/application.rb +++ b/config/application.rb @@ -20,6 +20,8 @@ class Application < Rails::Application # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] # config.i18n.default_locale = :de + config.active_job.queue_adapter = :delayed_job + # Do not swallow errors in after_commit/after_rollback callbacks. config.active_record.raise_in_transactional_callbacks = true end diff --git a/config/environments/development.rb b/config/environments/development.rb index b55e214..50162d1 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -36,6 +36,7 @@ # Raises helpful error messages. config.assets.raise_runtime_errors = true + config.action_mailer.delivery_method = :letter_opener # Raises error for missing translations # config.action_view.raise_on_missing_translations = true end diff --git a/config/initializers/core_extensions.rb b/config/initializers/core_extensions.rb new file mode 100644 index 0000000..557eef0 --- /dev/null +++ b/config/initializers/core_extensions.rb @@ -0,0 +1,16 @@ +module Enumerable + # clumps adjacent elements together + # >> [2,2,2,3,3,4,2,2,1].cluster{|x| x} + # => [[2, 2, 2], [3, 3], [4], [2, 2], [1]] + def cluster + cluster = [] + each do |element| + if cluster.last && yield(cluster.last.last) == yield(element) + cluster.last << element + else + cluster << [element] + end + end + cluster + end +end diff --git a/config/initializers/setup_mail.rb b/config/initializers/setup_mail.rb new file mode 100644 index 0000000..6c18985 --- /dev/null +++ b/config/initializers/setup_mail.rb @@ -0,0 +1,8 @@ +ActionMailer::Base.smtp_settings = { + address: "smtp.gmail.com", + port: "587", + enable_starttls_auto: true, + authentication: :plain, + user_name: ENV["email_user_name"], + password: ENV["email_password"] +} diff --git a/config/routes.rb b/config/routes.rb index 3f66539..d25bff5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,56 +1,23 @@ Rails.application.routes.draw do - # The priority is based upon order of creation: first created -> highest priority. - # See how all your routes lay out with "rake routes". - # You can have the root of your site routed with "root" - # root 'welcome#index' + root "home#index" + get "/home/about" => "home#about" - # Example of regular route: - # get 'products/:id' => 'catalog#view' + match "/delayed_job" => DelayedJobWeb, :anchor => false, via: [:get, :post] - # Example of named route that can be invoked with purchase_url(id: product.id) - # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase + resources :users, only: [:new, :create] do + resources :favourites, only: [:index] + get :edit, on: :collection + patch :update, on: :collection + end - # Example resource route (maps HTTP verbs to controller actions automatically): - # resources :products + resources :sessions, only: [:new, :create] do + delete :destroy, on: :collection + end - # Example resource route with options: - # resources :products do - # member do - # get 'short' - # post 'toggle' - # end - # - # collection do - # get 'sold' - # end - # end + resources :posts do + resources :favourites, only: [:destroy, :create] + resources :comments + end - # Example resource route with sub-resources: - # resources :products do - # resources :comments, :sales - # resource :seller - # end - - # Example resource route with more complex sub-resources: - # resources :products do - # resources :comments - # resources :sales do - # get 'recent', on: :collection - # end - # end - - # Example resource route with concerns: - # concern :toggleable do - # post 'toggle' - # end - # resources :posts, concerns: :toggleable - # resources :photos, concerns: :toggleable - - # Example resource route within a namespace: - # namespace :admin do - # # Directs /admin/products/* to Admin::ProductsController - # # (app/controllers/admin/products_controller.rb) - # resources :products - # end end diff --git a/config/schedule.rb b/config/schedule.rb new file mode 100644 index 0000000..c1df104 --- /dev/null +++ b/config/schedule.rb @@ -0,0 +1,26 @@ +# Use this file to easily define all of your cron jobs. +# +# It's helpful, but not entirely necessary to understand cron before proceeding. +# http://en.wikipedia.org/wiki/Cron + +# Example: +# +# set :output, "/path/to/my/cron_log.log" +# +# every 2.hours do +# command "/usr/bin/some_great_command" +# runner "MyModel.some_method" +# rake "some:great:rake:task" +# end +# +# every 4.days do +# runner "AnotherModel.prune_old_records" +# end + +# Learn more: http://github.com/javan/whenever +set :environment, "development" +set :output, {:error => "log/cron_error_log.log", :standard => "log/cron_log.log"} + +every :day, :at => '6:28pm' do + rake "post:comments" +end diff --git a/db/.DS_Store b/db/.DS_Store new file mode 100644 index 0000000..fce5605 Binary files /dev/null and b/db/.DS_Store differ diff --git a/db/migrate/20150609015548_create_titles.rb b/db/migrate/20150609015548_create_titles.rb deleted file mode 100644 index 099aa1b..0000000 --- a/db/migrate/20150609015548_create_titles.rb +++ /dev/null @@ -1,9 +0,0 @@ -class CreateTitles < ActiveRecord::Migration - def change - create_table :titles do |t| - t.text :body - - t.timestamps null: false - end - end -end diff --git a/db/migrate/20150609015835_create_contacts.rb b/db/migrate/20150609015835_create_contacts.rb deleted file mode 100644 index 5298b22..0000000 --- a/db/migrate/20150609015835_create_contacts.rb +++ /dev/null @@ -1,12 +0,0 @@ -class CreateContacts < ActiveRecord::Migration - def change - create_table :contacts do |t| - t.string :email - t.string :name - t.string :subject - t.text :message - - t.timestamps null: false - end - end -end diff --git a/db/migrate/20150609024027_create_posts.rb b/db/migrate/20150609024027_create_posts.rb new file mode 100644 index 0000000..691c505 --- /dev/null +++ b/db/migrate/20150609024027_create_posts.rb @@ -0,0 +1,10 @@ +class CreatePosts < ActiveRecord::Migration + def change + create_table :posts do |t| + t.string :title + t.text :body + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20150614212959_create_users.rb b/db/migrate/20150614212959_create_users.rb new file mode 100644 index 0000000..e22193e --- /dev/null +++ b/db/migrate/20150614212959_create_users.rb @@ -0,0 +1,12 @@ +class CreateUsers < ActiveRecord::Migration + def change + create_table :users do |t| + t.string :first_name + t.string :last_name + t.string :email + t.string :password_digest + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20150614213024_add_user_reference_to_posts.rb b/db/migrate/20150614213024_add_user_reference_to_posts.rb new file mode 100644 index 0000000..07fdc05 --- /dev/null +++ b/db/migrate/20150614213024_add_user_reference_to_posts.rb @@ -0,0 +1,5 @@ +class AddUserReferenceToPosts < ActiveRecord::Migration + def change + add_reference :posts, :user, index: true, foreign_key: true + end +end diff --git a/db/migrate/20150614213039_add_user_reference_to_comments.rb b/db/migrate/20150614213039_add_user_reference_to_comments.rb new file mode 100644 index 0000000..51fc510 --- /dev/null +++ b/db/migrate/20150614213039_add_user_reference_to_comments.rb @@ -0,0 +1,5 @@ +class AddUserReferenceToComments < ActiveRecord::Migration + def change + add_reference :comments, :user, index: true, foreign_key: true + end +end diff --git a/db/migrate/20150614214423_create_post_files.rb b/db/migrate/20150614214423_create_post_files.rb new file mode 100644 index 0000000..ec4cb97 --- /dev/null +++ b/db/migrate/20150614214423_create_post_files.rb @@ -0,0 +1,11 @@ +class CreatePostFiles < ActiveRecord::Migration + def change + create_table :post_files do |t| + t.string :name + t.text :description + t.references :post, index: true, foreign_key: true + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20150619002353_create_favourites.rb b/db/migrate/20150619002353_create_favourites.rb new file mode 100644 index 0000000..bf98360 --- /dev/null +++ b/db/migrate/20150619002353_create_favourites.rb @@ -0,0 +1,10 @@ +class CreateFavourites < ActiveRecord::Migration + def change + create_table :favourites do |t| + t.references :user, index: true, foreign_key: true + t.references :post, index: true, foreign_key: true + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20150619014257_create_tags.rb b/db/migrate/20150619014257_create_tags.rb new file mode 100644 index 0000000..965cd7a --- /dev/null +++ b/db/migrate/20150619014257_create_tags.rb @@ -0,0 +1,9 @@ +class CreateTags < ActiveRecord::Migration + def change + create_table :tags do |t| + t.string :name + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20150619014310_create_taggings.rb b/db/migrate/20150619014310_create_taggings.rb new file mode 100644 index 0000000..0dd5c85 --- /dev/null +++ b/db/migrate/20150619014310_create_taggings.rb @@ -0,0 +1,10 @@ +class CreateTaggings < ActiveRecord::Migration + def change + create_table :taggings do |t| + t.references :tag, index: true, foreign_key: true + t.references :post, index: true, foreign_key: true + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20150620220111_create_delayed_jobs.rb b/db/migrate/20150620220111_create_delayed_jobs.rb new file mode 100644 index 0000000..27fdcf6 --- /dev/null +++ b/db/migrate/20150620220111_create_delayed_jobs.rb @@ -0,0 +1,22 @@ +class CreateDelayedJobs < ActiveRecord::Migration + def self.up + create_table :delayed_jobs, force: true do |table| + table.integer :priority, default: 0, null: false # Allows some jobs to jump to the front of the queue + table.integer :attempts, default: 0, null: false # Provides for retries, but still fail eventually. + table.text :handler, null: false # YAML-encoded string of the object that will do work + table.text :last_error # reason for last failure (See Note below) + table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future. + table.datetime :locked_at # Set when a client is working on this object + table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead) + table.string :locked_by # Who is working on this object (if locked) + table.string :queue # The name of the queue this job is in + table.timestamps null: true + end + + add_index :delayed_jobs, [:priority, :run_at], name: "delayed_jobs_priority" + end + + def self.down + drop_table :delayed_jobs + end +end diff --git a/db/migrate/20150703013105_add_asset_to_posts.rb b/db/migrate/20150703013105_add_asset_to_posts.rb new file mode 100644 index 0000000..bb29633 --- /dev/null +++ b/db/migrate/20150703013105_add_asset_to_posts.rb @@ -0,0 +1,5 @@ +class AddAssetToPosts < ActiveRecord::Migration + def change + add_column :posts, :asset, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index a5043cb..7812a93 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150609015835) do +ActiveRecord::Schema.define(version: 20150703013105) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -26,8 +26,13 @@ t.text "body" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.integer "post_id" + t.integer "user_id" end + add_index "comments", ["post_id"], name: "index_comments_on_post_id", using: :btree + add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree + create_table "contacts", force: :cascade do |t| t.string "email" t.string "name" @@ -37,10 +42,90 @@ t.datetime "updated_at", null: false end + create_table "delayed_jobs", force: :cascade do |t| + t.integer "priority", default: 0, null: false + t.integer "attempts", default: 0, null: false + t.text "handler", null: false + t.text "last_error" + t.datetime "run_at" + t.datetime "locked_at" + t.datetime "failed_at" + t.string "locked_by" + t.string "queue" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree + + create_table "favourites", force: :cascade do |t| + t.integer "user_id" + t.integer "post_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "favourites", ["post_id"], name: "index_favourites_on_post_id", using: :btree + add_index "favourites", ["user_id"], name: "index_favourites_on_user_id", using: :btree + + create_table "post_files", force: :cascade do |t| + t.string "name" + t.text "description" + t.integer "post_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "post_files", ["post_id"], name: "index_post_files_on_post_id", using: :btree + + create_table "posts", force: :cascade do |t| + t.string "title" + t.text "body" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "user_id" + t.string "asset" + end + + add_index "posts", ["user_id"], name: "index_posts_on_user_id", using: :btree + + create_table "taggings", force: :cascade do |t| + t.integer "tag_id" + t.integer "post_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "taggings", ["post_id"], name: "index_taggings_on_post_id", using: :btree + add_index "taggings", ["tag_id"], name: "index_taggings_on_tag_id", using: :btree + + create_table "tags", force: :cascade do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "titles", force: :cascade do |t| t.text "body" t.datetime "created_at", null: false t.datetime "updated_at", null: false 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 + end + + add_foreign_key "comments", "posts" + add_foreign_key "comments", "users" + add_foreign_key "favourites", "posts" + add_foreign_key "favourites", "users" + add_foreign_key "post_files", "posts" + add_foreign_key "posts", "users" + add_foreign_key "taggings", "posts" + add_foreign_key "taggings", "tags" end diff --git a/db/seeds.rb b/db/seeds.rb index 4edb1e8..a6f8dda 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -5,3 +5,7 @@ # # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) # Mayor.create(name: 'Emanuel', city: cities.first) + +['1','2','3','4','5','6','7'].each do |num| + Tag.create name: num +end diff --git a/erd.pdf b/erd.pdf new file mode 100644 index 0000000..12bd30f Binary files /dev/null and b/erd.pdf differ diff --git a/lib/tasks/post.rake b/lib/tasks/post.rake new file mode 100644 index 0000000..a9efbe7 --- /dev/null +++ b/lib/tasks/post.rake @@ -0,0 +1,32 @@ +namespace :post do + desc "Tasks associated with posts" + task comments: :environment do + new_comments = [] + comments = Comment.includes(post: :user).where('created_at > ?', 1.day.ago) + comments.each {|comment| new_comments << comment} + #Comment.where("created_at > ?", 1.day.ago).each {|comment| new_comments << comment} + sorted_new_comments = new_comments.sort_by { |comment| comment.post.user } + #new_comments.each { |comment| p comment.post.user } + #p sorted_new_comments == new_comments + #sorted_new_comments.each { |comment| p comment.post.user } + @clustered_comments = sorted_new_comments.cluster { |comment| comment.post.user } + @clustered_comments.each {|c| p c[0].post.user.email} + PostsMailer.notify_post_owners_summary(@clustered_comments).deliver_now + end +end + + +# Stretch: Setup a rake task that does the following: +# Make a summary (list) of all newly created comments that that day for posts +# Send an email with the summary to posts owners + +#find all comments less than a day old +# +#group them somehow +# +#User.all.each +#Post.all.each do |post| +# post.comments.where("created_at < ?", 1.day.ago).each do |comment| +# p comment.body +# end +#end diff --git a/public/uploads/post/asset/15/Photo_on_2015-06-20_at_7.49_AM.jpg b/public/uploads/post/asset/15/Photo_on_2015-06-20_at_7.49_AM.jpg new file mode 100644 index 0000000..4209dee Binary files /dev/null and b/public/uploads/post/asset/15/Photo_on_2015-06-20_at_7.49_AM.jpg differ diff --git a/public/uploads/post/asset/16/config.ru b/public/uploads/post/asset/16/config.ru new file mode 100644 index 0000000..bd83b25 --- /dev/null +++ b/public/uploads/post/asset/16/config.ru @@ -0,0 +1,4 @@ +# This file is used by Rack-based servers to start the application. + +require ::File.expand_path('../config/environment', __FILE__) +run Rails.application diff --git a/test/controllers/comments_controller_test.rb b/test/controllers/comments_controller_test.rb new file mode 100644 index 0000000..2ec71b4 --- /dev/null +++ b/test/controllers/comments_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class CommentsControllerTest < ActionController::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/controllers/favourites_controller_test.rb b/test/controllers/favourites_controller_test.rb new file mode 100644 index 0000000..31785f5 --- /dev/null +++ b/test/controllers/favourites_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class FavouritesControllerTest < ActionController::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/controllers/posts_controller_test.rb b/test/controllers/posts_controller_test.rb new file mode 100644 index 0000000..7a6ee4f --- /dev/null +++ b/test/controllers/posts_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class PostsControllerTest < ActionController::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/controllers/sessions_controller_test.rb b/test/controllers/sessions_controller_test.rb new file mode 100644 index 0000000..d30ebc3 --- /dev/null +++ b/test/controllers/sessions_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class SessionsControllerTest < ActionController::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb new file mode 100644 index 0000000..d23f182 --- /dev/null +++ b/test/controllers/users_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class UsersControllerTest < ActionController::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/fixtures/favourites.yml b/test/fixtures/favourites.yml new file mode 100644 index 0000000..a5aae8c --- /dev/null +++ b/test/fixtures/favourites.yml @@ -0,0 +1,9 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + user_id: + post_id: + +two: + user_id: + post_id: diff --git a/test/fixtures/contacts.yml b/test/fixtures/post_files.yml similarity index 54% rename from test/fixtures/contacts.yml rename to test/fixtures/post_files.yml index db36c32..20f209c 100644 --- a/test/fixtures/contacts.yml +++ b/test/fixtures/post_files.yml @@ -1,13 +1,11 @@ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html one: - email: MyString name: MyString - subject: MyString - message: MyText + description: MyText + post_id: two: - email: MyString name: MyString - subject: MyString - message: MyText + description: MyText + post_id: diff --git a/test/fixtures/titles.yml b/test/fixtures/posts.yml similarity index 78% rename from test/fixtures/titles.yml rename to test/fixtures/posts.yml index e46420e..e192dee 100644 --- a/test/fixtures/titles.yml +++ b/test/fixtures/posts.yml @@ -1,7 +1,9 @@ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html one: + title: MyString body: MyText two: + title: MyString body: MyText diff --git a/test/fixtures/taggings.yml b/test/fixtures/taggings.yml new file mode 100644 index 0000000..cf134d9 --- /dev/null +++ b/test/fixtures/taggings.yml @@ -0,0 +1,9 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + tag_id: + post_id: + +two: + tag_id: + post_id: diff --git a/test/fixtures/tags.yml b/test/fixtures/tags.yml new file mode 100644 index 0000000..56066c6 --- /dev/null +++ b/test/fixtures/tags.yml @@ -0,0 +1,7 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + +two: + name: MyString diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml new file mode 100644 index 0000000..dacc14f --- /dev/null +++ b/test/fixtures/users.yml @@ -0,0 +1,13 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + first_name: MyString + last_name: MyString + email: MyString + password_digest: MyString + +two: + first_name: MyString + last_name: MyString + email: MyString + password_digest: MyString diff --git a/test/mailers/posts_mailer_test.rb b/test/mailers/posts_mailer_test.rb new file mode 100644 index 0000000..b5a885f --- /dev/null +++ b/test/mailers/posts_mailer_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class PostsMailerTest < ActionMailer::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/mailers/previews/posts_mailer_preview.rb b/test/mailers/previews/posts_mailer_preview.rb new file mode 100644 index 0000000..ef4ebb9 --- /dev/null +++ b/test/mailers/previews/posts_mailer_preview.rb @@ -0,0 +1,4 @@ +# Preview all emails at http://localhost:3000/rails/mailers/posts_mailer +class PostsMailerPreview < ActionMailer::Preview + +end diff --git a/test/models/favourite_test.rb b/test/models/favourite_test.rb new file mode 100644 index 0000000..8bbf41d --- /dev/null +++ b/test/models/favourite_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class FavouriteTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/post_file_test.rb b/test/models/post_file_test.rb new file mode 100644 index 0000000..73e8e0d --- /dev/null +++ b/test/models/post_file_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class PostFileTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/title_test.rb b/test/models/post_test.rb similarity index 64% rename from test/models/title_test.rb rename to test/models/post_test.rb index 954b9e3..6d9d463 100644 --- a/test/models/title_test.rb +++ b/test/models/post_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class TitleTest < ActiveSupport::TestCase +class PostTest < ActiveSupport::TestCase # test "the truth" do # assert true # end diff --git a/test/models/contact_test.rb b/test/models/tag_test.rb similarity index 63% rename from test/models/contact_test.rb rename to test/models/tag_test.rb index ccef1f9..b8498a1 100644 --- a/test/models/contact_test.rb +++ b/test/models/tag_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class ContactTest < ActiveSupport::TestCase +class TagTest < ActiveSupport::TestCase # test "the truth" do # assert true # end diff --git a/test/models/tagging_test.rb b/test/models/tagging_test.rb new file mode 100644 index 0000000..77dbeac --- /dev/null +++ b/test/models/tagging_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class TaggingTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/user_test.rb b/test/models/user_test.rb new file mode 100644 index 0000000..82f61e0 --- /dev/null +++ b/test/models/user_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class UserTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end