Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
dc1957c
add routes tweets#index and index view for tweets
panjau Aug 29, 2018
342cfb4
1.add user registration name field, 2.authenticate user, only login u…
panjau Aug 29, 2018
863a75a
set up admin authentication
panjau Aug 29, 2018
4a8c1ca
link user and tweet model
panjau Aug 29, 2018
acdd0f4
add rake tweet
panjau Aug 29, 2018
3e972c3
1.add bootstrap gem, and related setting, 2.implement Create action i…
panjau Aug 30, 2018
dfbfe5e
add style.scss, display tweet item in index.html
panjau Aug 30, 2018
6f64d51
implement display popular user in index.html
panjau Aug 30, 2018
d509d3e
add nav bar icon and content
panjau Aug 30, 2018
6175ecb
add follow/unfollow function & user's tweets index page
panjau Aug 30, 2018
4a3f53c
add followings page
panjau Aug 31, 2018
7d227b4
fix following isse
panjau Aug 31, 2018
54be9d7
modify tweets username format
panjau Aug 31, 2018
5871a82
modify followings naming
panjau Aug 31, 2018
c893fc3
add followers function
panjau Aug 31, 2018
ae652df
add follow/unfollow button on tweets index page
panjau Aug 31, 2018
890147d
define relation between tweet, user, and comment
panjau Aug 31, 2018
bd58a6d
add reply feature
panjau Aug 31, 2018
91728bb
add like function and edit user profile
panjau Aug 31, 2018
773064d
add admin/tweets#index
panjau Aug 31, 2018
b0e674c
fix incorrect redirect path in #like #unlike
panjau Aug 31, 2018
5e1b5f0
fix can't follow self issue
panjau Aug 31, 2018
687c20c
fix admin #destroy incorrect redirect path issue
panjau Aug 31, 2018
addd47a
add admin can see all user list function
panjau Aug 31, 2018
2400965
modify for Heroku production
panjau Aug 31, 2018
5101975
remove sqlite3
panjau Aug 31, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ gem 'ffaker'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.1.4'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use Puma as the app server
gem 'puma', '~> 3.7'
gem 'bootstrap-sass', '~> 3.3.7'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
Expand All @@ -40,6 +39,11 @@ gem 'jbuilder', '~> 2.5'

# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
gem 'jquery-rails'

group :production do
gem 'pg', '~> 0.20'
end

group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
Expand Down
15 changes: 15 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,16 @@ GEM
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
arel (8.0.0)
autoprefixer-rails (9.1.3)
execjs
bcrypt (3.1.12)
bcrypt (3.1.12-java)
bcrypt (3.1.12-x64-mingw32)
bcrypt (3.1.12-x86-mingw32)
bindex (0.5.0)
bootstrap-sass (3.3.7)
autoprefixer-rails (>= 5.2.1)
sass (>= 3.3.4)
builder (3.2.3)
byebug (10.0.2)
capybara (2.18.0)
Expand Down Expand Up @@ -97,6 +102,10 @@ GEM
jbuilder (2.7.0)
activesupport (>= 4.2.0)
multi_json (>= 1.2)
jquery-rails (4.3.3)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
Expand Down Expand Up @@ -124,6 +133,9 @@ GEM
nokogiri (1.8.4-x86-mingw32)
mini_portile2 (~> 2.3.0)
orm_adapter (0.5.0)
pg (0.21.0)
pg (0.21.0-x64-mingw32)
pg (0.21.0-x86-mingw32)
public_suffix (3.0.2)
puma (3.12.0)
puma (3.12.0-java)
Expand Down Expand Up @@ -251,6 +263,7 @@ PLATFORMS
x86-mswin32

DEPENDENCIES
bootstrap-sass (~> 3.3.7)
byebug
capybara (~> 2.13)
carrierwave
Expand All @@ -259,7 +272,9 @@ DEPENDENCIES
factory_bot_rails
ffaker
jbuilder (~> 2.5)
jquery-rails
listen (>= 3.0.5, < 3.2)
pg (~> 0.20)
puma (~> 3.7)
rails (~> 5.1.4)
rails-controller-testing
Expand Down
2 changes: 2 additions & 0 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@
//= require rails-ujs
//= require turbolinks
//= require_tree .
//= require jquery
//= require bootstrap-sprockets
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* files in this directory. Styles in this file should be added after the last require_* statement.
* It is generally better to create a new file per style scope.
*
*= require_tree .
*= require_self
*/
@import "bootstrap-sprockets";
@import "bootstrap";
@import 'style'
50 changes: 50 additions & 0 deletions app/assets/stylesheets/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

.form-style{
border:2px grey solid;
border-radius: 10px;
margin: 10px;
}

.button-tweet{
border-radius: 5px;
padding: 5px 15px;
margin-right: 0px;
margin-bottom: 10px;
}

.tweet-item{
margin: 10px;
border: 1px solid #ddd;
padding: 10px 10px;
}


.tweet-avatar{
margin: 0px 0px 0px 0px;
width: 50px;
}

.nav-avatar{
padding: 0px 0px;
margin: 0px 0px;
}

.navbar-nav > li > a {
padding: 0px 0px;
}

.user-avatar{
margin: 0px 0px 0px 0px;
width: 200px
}

.user-item {
border: 1px solid #ddd;
border-radius: 4px;
padding: 4px;
margin-bottom: 20px;
}

.reply-area {
padding: 15px 15px;
}
12 changes: 12 additions & 0 deletions app/controllers/admin/base_controller.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
class Admin::BaseController < ApplicationController
before_action :authenticate_user!
before_action :authenticate_admin


private

def authenticate_admin
unless current_user.admin?
flash[:alert] = "Not allow!"
redirect_to root_path
end
end

end
5 changes: 5 additions & 0 deletions app/controllers/admin/tweets_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
class Admin::TweetsController < Admin::BaseController
def index
@tweets = Tweet.all.order(created_at: :desc)
end

def destroy
@tweet = Tweet.find(params[:id])
@tweet.destroy
redirect_to admin_root_path
flash[:alert] = "Tweet has been deleted!"
end
end
1 change: 1 addition & 0 deletions app/controllers/admin/users_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
class Admin::UsersController < Admin::BaseController
def index
@users = User.order(followers_count: :desc)
end
end
11 changes: 10 additions & 1 deletion app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception

before_action :configure_permitted_parameters, if: :devise_controller?
before_action :authenticate_user!
# 請參考 Devise 文件自訂表單後通過 Strong Parameters 的方法
# https://github.com/plataformatec/devise#strong-parameters
# 注意有 sign_up 和 account_update 兩種參數要處理

protected
# Devise 客製化屬性的使用說明: https://github.com/plataformatec/devise#strong-parameters
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
devise_parameter_sanitizer.permit(:account_update, keys: [:name])
end

end
15 changes: 15 additions & 0 deletions app/controllers/followships_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
class FollowshipsController < ApplicationController
def create

@followship = current_user.followships.build(following_id: params[:following_id])
if @followship.user_id != @followship.following_id
if @followship.save
flash[:notice] = "Successfilly followed"
redirect_back(fallback_location: tweets_user_path(params[:following_id]))
else
flash[:alert] = @followship.errors.full_messages.to_sentence
redirect_back(fallback_location: tweets_user_path(params[:following_id]))
end
end
end

def destroy
@followship = current_user.followships.where(following_id: params[:id]).first
@followship.destroy
flash[:alert] = "Followship destroyed"
redirect_back(fallback_location: tweets_user_path(params[:id]))
end
end
14 changes: 14 additions & 0 deletions app/controllers/replies_controller.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
class RepliesController < ApplicationController

def index
@tweet = Tweet.find(params[:tweet_id])
@replies = @tweet.replies
@reply = Reply.new
end

def create
@tweet = Tweet.find(params[:tweet_id])
@reply = @tweet.replies.build(replied_params)
@reply.user = current_user
@reply.save!
redirect_to tweet_replies_path(@tweet)
end

private

def replied_params
params.require(:reply).permit(:comment)
end

end
27 changes: 26 additions & 1 deletion app/controllers/tweets_controller.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,41 @@
class TweetsController < ApplicationController

def index
@users # 基於測試規格,必須講定變數名稱,請用此變數中存放關注人數 Top 10 的使用者資料
@tweets = Tweet.all.order(created_at: :desc)
@tweet = Tweet.new
@users = User.order(followers_count: :desc).limit(10)# 基於測試規格,必須講定變數名稱,請用此變數中存放關注人數 Top 10 的使用者資料
end

def create
@tweet = Tweet.new(tweet_params)
@tweet.user = current_user
if @tweet.save
flash[:notice] = "You Tweet was successfully created"
redirect_to tweets_path
else
flash.now[:alert] = "Your Tweet was failed to create"
render :index
end
end

def like
@tweet = Tweet.find(params[:id])
@tweet.likes.create!(user: current_user)
redirect_back(fallback_location: tweets_path)
end

def unlike
@tweet = Tweet.find(params[:id])
like_items = Like.where(tweet: @tweet, user: current_user)
like_items.destroy_all
redirect_back(fallback_location: tweets_path)
end


private

def tweet_params
params.require(:tweet).permit(:description)
end

end
22 changes: 19 additions & 3 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@
class UsersController < ApplicationController

def tweets
@user = User.find(params[:id])
@tweets = @user.tweets.order(created_at: :desc)
end

def edit
@user = User.find(params[:id])
if @user != current_user
redirect_to tweets_user_path(@user)
end
end

def update
@user = User.find(params[:id])
@user.update(user_params)
redirect_to tweets_user_path(@user)
end

def followings
@followings # 基於測試規格,必須講定變數名稱
@user = User.find(params[:id])
@followings = @user.followings.order(created_at: :desc) # 基於測試規格,必須講定變數名稱
end

def followers
@followers # 基於測試規格,必須講定變數名稱
@user = User.find(params[:id])
@followers = @user.followers.order(created_at: :desc)# 基於測試規格,必須講定變數名稱
end

def likes
@likes # 基於測試規格,必須講定變數名稱
@user = User.find(params[:id])
@likes = @user.liked_tweets.order(created_at: :desc)# 基於測試規格,必須講定變數名稱
end

def user_params
params.require(:user).permit(:name, :introduction, :avatar)
end

end
2 changes: 2 additions & 0 deletions app/models/followship.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class Followship < ApplicationRecord
validates :following_id, uniqueness: { scope: :user_id }
belongs_to :user
belongs_to :following, class_name: "User", counter_cache: :followers_count

end
2 changes: 2 additions & 0 deletions app/models/like.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
class Like < ApplicationRecord
belongs_to :user, counter_cache: true
belongs_to :tweet, counter_cache: true
end
2 changes: 2 additions & 0 deletions app/models/reply.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
class Reply < ApplicationRecord
belongs_to :user
belongs_to :tweet, counter_cache: true
end
9 changes: 9 additions & 0 deletions app/models/tweet.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
class Tweet < ApplicationRecord
validates_length_of :description, maximum: 140
belongs_to :user
has_many :replies, dependent: :destroy
has_many :replied_users, through: :replies, source: :user

has_many :likes, dependent: :destroy
has_many :liked_users, through: :likes, source: :user

def is_like?(user)
self.liked_users.include?(user)
end
end
21 changes: 21 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,32 @@ class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable

validates_presence_of :name
validates_uniqueness_of :name
has_many :tweets, dependent: :destroy
has_many :followships, dependent: :destroy
has_many :followings, through: :followships

has_many :inverse_followships, class_name: "Followship", foreign_key: "following_id"
has_many :followers, through: :inverse_followships, source: :user

has_many :replies, dependent: :destroy
has_many :replied_tweets, through: :replies, source: :tweet

has_many :likes, dependent: :destroy
has_many :liked_tweets, through: :likes, source: :tweet

mount_uploader :avatar, AvatarUploader

# 需要 app/views/devise 裡找到樣板,加上 name 屬性
# 並參考 Devise 文件自訂表單後通過 Strong Parameters 的方法
validates_presence_of :name
# 加上驗證 name 不能重覆 (關鍵字提示: uniqueness)
def admin?
self.role == "admin"
end

def following?(user)
self.followings.include?(user)
end
end
Loading