Skip to content
Open
5 changes: 5 additions & 0 deletions app/controllers/api_v1/messages_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class ApiV1::MessagesController < ApplicationController
def index
@messages = Message.all
end
end
4 changes: 3 additions & 1 deletion app/controllers/comments_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ def destroy
@comment = current_user.comments.find( params[:id] )
@comment.destroy

redirect_to :back
respond_to do |format|
format.js
end
end

protected
Expand Down
21 changes: 6 additions & 15 deletions app/controllers/messages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,17 @@ class MessagesController < ApplicationController
before_action :authenticate_user!, :except => [:index, :show]

def index
# TODO: fix N+1 queries for user and comments
@messages = Message.order("id DESC").page( params[:page] )

if params[:status] == "pending"
# TODO: @messages = @messages.pending
@messages = @messages.where( :status => "pending" )
elsif params[:status] == "completed"
# TODO: @messages = @messages.completed
@messages = @messages.where( :status => "completed" )
end

if params[:days]
# TODO: @messages = @messages.within_days(params[:days].to_i)
@messages = @messages.where( ["created_at >= ?", Time.now - params[:days].to_i.days ] )
end
@messages = Message.includes(:user, :comments).order("id DESC").page( params[:page] )
@messages = @messages.pending if params[:status] == "pending"
@messages = @messages.completed if params[:status] == "completed"
@messages = @messages.within_days(params[:days].to_i) if params[:days]
end

def show
@message = Message.find( params[:id] )
@comment = Comment.new
@users_sub = @message.subed_by_users
@users_liked = @message.liked_by_users
end

def new
Expand Down
4 changes: 4 additions & 0 deletions app/models/like.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class Like < ActiveRecord::Base
belongs_to :user
belongs_to :message
end
13 changes: 13 additions & 0 deletions app/models/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,21 @@ class Message < ActiveRecord::Base

has_many :comments, :dependent => :destroy

has_many :subscriptions, :dependent => :destroy
has_many :subed_by_users, -> { distinct }, :through => :subscriptions, :source => :user

has_many :likes, :dependent => :destroy
has_many :liked_by_users, -> { distinct }, :through => :likes, :source => :user

def last_comment_summary
self.comments.last.try(:content).try(:truncate, 20)
end

scope :pending, -> { where( status: "pending" ) }
scope :completed, -> { where( status: "completed" ) }
scope :within_days, ->(time) { where("created_at >= ?", Time.now - time.days) }
# According to rails api,here I quote,"Using a class method is the preferred way to accept arguments for scopes."
# def self.within_days(time)
# where( ["created_at >= ?", Time.now - time.days ] )
# end
end
4 changes: 4 additions & 0 deletions app/models/subscription.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class Subscription < ActiveRecord::Base
belongs_to :user
belongs_to :message
end
8 changes: 7 additions & 1 deletion app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@ class User < ActiveRecord::Base
has_many :messages
has_many :comments

has_many :subscriptions, :dependent => :destroy
has_many :sub_messages, -> { distinct }, :through => :subscriptions, :source => :message

has_many :likes, :dependent => :destroy
has_many :like_messages, -> { distinct }, :through => :likes, :source => :message

def display_name
self.email.split("@").first
end

def posts_count
# TODO: 請完成我
self.messages.count + self.comments.count
end

def words_count
Expand Down
3 changes: 3 additions & 0 deletions app/views/api_v1/messages/index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
json.data @messages do |msg|
json.(msg, :id, :status, :category_name, :title, :content, :created_at)
end
1 change: 1 addition & 0 deletions app/views/comments/destroy.js.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$("#<%= @comment.id %>_comment").remove();
29 changes: 19 additions & 10 deletions app/views/messages/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
<h2><%= @message.title %></h2>

<%= simple_format @message.content %>
<b>Subscribed by</b>
<% @users_sub.each do |user| %>
<p><%= user.display_name %></p>
<% end %>

<b>Liked by</b>
<% @users_liked.each do |user| %>
<p><%= user.display_name %></p>
<% end %>

<h2>Comments list</h2>

Expand All @@ -17,15 +26,15 @@

<% end %>

<% @message.comments.each do |comment| %>

<p><%= simple_format comment.content %> at <%= comment.created_at.to_s(:short) %> by <%= comment.user.display_name %>

<% if comment.user == current_user %>
<%# TODO: 修改成 AJAX 版本的刪除 %>
<%= link_to "Delete", message_comment_path(@message, comment), :method => :delete, :data => { :confirm => "Are u sure?"} %>
<% end %>
</p>

<% @message.comments.each do |comment| %>
<div id="<%= comment.id %>_comment">
<p><%= simple_format comment.content %> at <%= comment.created_at.to_s(:short) %> by <%= comment.user.display_name %>

<% if comment.user == current_user %>
<%# TODO: 修改成 AJAX 版本的刪除 %>
<%= link_to "Delete", message_comment_path(@message, comment), :method => :delete, :remote => true %>
<% end %>
</p>
</div>
<% end %>

56 changes: 3 additions & 53 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,59 +4,9 @@
resources :messages do
resources :comments
end

# 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 'messages#index'

# Example of regular route:
# get 'products/:id' => 'catalog#view'

# Example of named route that can be invoked with purchase_url(id: product.id)
# get 'products/:id/purchase' => 'catalog#purchase', as: :purchase

# Example resource route (maps HTTP verbs to controller actions automatically):
# resources :products

# Example resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# 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
scope :path => '/api/v1/', :module => "api_v1", :as => 'v1', :defaults => { :format => :json } do
resources :messages, only: :index
end
end
12 changes: 12 additions & 0 deletions db/migrate/20161111164452_create_subscriptions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class CreateSubscriptions < ActiveRecord::Migration
def change
create_table :subscriptions do |t|
t.integer :user_id
t.integer :message_id

t.timestamps null: false
end
add_index :subscriptions, :user_id
add_index :subscriptions, :message_id
end
end
12 changes: 12 additions & 0 deletions db/migrate/20161111164905_create_likes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class CreateLikes < ActiveRecord::Migration
def change
create_table :likes do |t|
t.integer :user_id
t.integer :message_id

t.timestamps null: false
end
add_index :likes, :user_id
add_index :likes, :message_id
end
end
22 changes: 21 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20150728165437) do
ActiveRecord::Schema.define(version: 20161111164905) do

create_table "comments", force: :cascade do |t|
t.text "content"
Expand All @@ -23,6 +23,16 @@

add_index "comments", ["message_id"], name: "index_comments_on_message_id"

create_table "likes", force: :cascade do |t|
t.integer "user_id"
t.integer "message_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

add_index "likes", ["message_id"], name: "index_likes_on_message_id"
add_index "likes", ["user_id"], name: "index_likes_on_user_id"

create_table "messages", force: :cascade do |t|
t.string "title"
t.text "content"
Expand All @@ -36,6 +46,16 @@
add_index "messages", ["status"], name: "index_messages_on_status"
add_index "messages", ["user_id"], name: "index_messages_on_user_id"

create_table "subscriptions", force: :cascade do |t|
t.integer "user_id"
t.integer "message_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

add_index "subscriptions", ["message_id"], name: "index_subscriptions_on_message_id"
add_index "subscriptions", ["user_id"], name: "index_subscriptions_on_user_id"

create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
Expand Down
6 changes: 4 additions & 2 deletions lib/tasks/dev.rake
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ namespace :dev do
:status => ["pending", "completed"].sample,
:content => Faker::Lorem.paragraph,
:user => users.sample,
:created_at => Time.now - rand(30).days )
:created_at => Time.now - rand(30).days,
:subed_by_users => users.sample(2),
:liked_by_users => users.sample(2) )
5.times do
m.comments.create!( :content => Faker::Lorem.paragraph,
:user => users.sample )
end
end
end

end
end
5 changes: 5 additions & 0 deletions spec/models/like_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require 'rails_helper'

RSpec.describe Like, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end
5 changes: 5 additions & 0 deletions spec/models/subscription_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require 'rails_helper'

RSpec.describe Subscription, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end
6 changes: 3 additions & 3 deletions spec/models/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@

describe "#words_count" do
before do
# TODO: 加 Message 和 Comment 測試資料
msg = Message.create!( :user => @user, :title => "Jacob is doing final exam", :content => "feels good")
comment = Comment.create!( :user => @user, :message => msg, :content=> "get it done" )
end

it "加總該使用者的所有 Mesasge 和 Comment 的總字數" do
# TODO: 測試 words_count 方法

expect( @user.words_count ).to eq(10)
end
end

Expand Down