diff --git a/Gemfile b/Gemfile index 3d2db6c..043dda9 100644 --- a/Gemfile +++ b/Gemfile @@ -35,7 +35,6 @@ end group :test do gem 'capybara' - gem 'factory_girl' gem 'mongoid-rspec', :require => false gem 'database_cleaner' end @@ -43,4 +42,5 @@ end group :test, :development do gem "rspec-rails", ">= 2.8.1" gem 'pry-rails' + gem 'factory_girl_rails' end diff --git a/app/assets/javascripts/angularjs.js.coffee b/app/assets/javascripts/angularjs.js.coffee index bbf50dd..5631e76 100644 --- a/app/assets/javascripts/angularjs.js.coffee +++ b/app/assets/javascripts/angularjs.js.coffee @@ -8,4 +8,5 @@ @app.config(["$httpProvider", (provider) -> provider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content') + provider.defaults.headers.common['Accept'] = 'application/json' ]) diff --git a/app/assets/javascripts/angularjs/archives.js.coffee b/app/assets/javascripts/angularjs/archives.js.coffee new file mode 100644 index 0000000..8df73c9 --- /dev/null +++ b/app/assets/javascripts/angularjs/archives.js.coffee @@ -0,0 +1,29 @@ +@app.controller 'ArchivesController', ($scope, $http, $location, $timeout)-> + url = "/archives.json" + $http.get(url).success (res)-> + $scope.start_with = res.start_with + $scope.posts = res.posts + + $scope.no_more_flag = false + $scope.loading_flag = false + + $scope.load = ()-> + $scope.loading_flag = true + $http( + url: url + method: 'GET' + params: + start_with: $scope.start_with + ).success (res)-> + $scope.no_more_flag = true if res.posts.length == 0 + $scope.start_with = res.start_with + $scope.posts = $scope.posts.concat(res.posts) + $timeout -> + $scope.loading_flag = false + , 500 + $timeout -> + $scope.no_more_flag = false + , 3000 + + $scope.visit = (id)-> + window.location.href = ("/blogs/" + id) diff --git a/app/assets/javascripts/angularjs/comments.js.coffee b/app/assets/javascripts/angularjs/comments.js.coffee index 7992838..028050b 100644 --- a/app/assets/javascripts/angularjs/comments.js.coffee +++ b/app/assets/javascripts/angularjs/comments.js.coffee @@ -1,5 +1,5 @@ -@app.controller 'CommentsController', ($scope, $http, $location)-> - url = $location.absUrl() + "/comments" +@app.controller 'CommentsController', ($scope, $http, $location, $timeout)-> + url = $location.absUrl() + "/comments.json" $http.get(url).success (data)-> console.log data diff --git a/app/assets/stylesheets/archives.css.scss b/app/assets/stylesheets/archives.css.scss index 39af0e8..41aca03 100644 --- a/app/assets/stylesheets/archives.css.scss +++ b/app/assets/stylesheets/archives.css.scss @@ -37,4 +37,12 @@ } } } + + .no-more-field p { + text-align: center; + color: #444444; + border-bottom: 1px solid #DDDDDD; + padding-bottom: 0.5rem; + padding-top: 1rem; + } } diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index e8065d9..6ef36d1 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,3 +1,13 @@ class ApplicationController < ActionController::Base protect_from_forgery + + helper_method :format_time, :format_date + + def format_time(time) + time.strftime("%Y-%m-%d %H:%M") + end + + def format_date(time) + time.strftime("%Y-%m-%d") + end end diff --git a/app/controllers/archives_controller.rb b/app/controllers/archives_controller.rb index 88380c4..79ecfcd 100644 --- a/app/controllers/archives_controller.rb +++ b/app/controllers/archives_controller.rb @@ -1,9 +1,59 @@ class ArchivesController < ApplicationController def index - @posts = Post.all + type = map[archive_params[:type]] + limit = 10 + start_with = archive_params[:start_with] + @posts = Post.limit(limit).desc(:created_at) + if type + @posts = @posts.where(type: type) + end + + if start_with + @posts = @posts.where(:created_at.lt => Time.at(start_with.to_i)) + end + + #update start_with + unless @posts.empty? + start_with = @posts[-1].created_at.to_i.to_s + end + + respond_to do |format| + format.json do + render :json => { + posts: @posts.collect { |post| build_summary(post) }, + start_with: start_with + } + end + format.html + end end def archive_params - params.permit(:type) + params.permit(:type, :start_with) + end + + private + def map + { + "life"=> "生活", + "tech"=> "技术", + "creator"=> "创业" + } + end + + def archive_params + params.permit(:type, :start_with, :format) + end + + def build_summary(post) + { + title: post.title, + type: post.type, + created_at: format_date(post.created_at), + id: post.id.to_s, + liked_count: post.likes.size, + visited_count: post.visited_count, + labels: post.labels_content + } end end diff --git a/app/controllers/blogs_controller.rb b/app/controllers/blogs_controller.rb index 50730dd..b4f9800 100644 --- a/app/controllers/blogs_controller.rb +++ b/app/controllers/blogs_controller.rb @@ -13,17 +13,9 @@ class BlogsController < ApplicationController def show @post = Post.find(params[:id]) - @prev = Post.where(:created_at.lt => @post.created_at).desc(:created_at).where(:id.ne => @post.id).first - @next = Post.where(:created_at.gt => @post.created_at).asc(:created_at).where(:id.ne => @post.id).first + created_at = Time.at(@post.created_at.to_f) + @prev = Post.where(:created_at.lt => created_at).desc(:created_at).first + @next = Post.where(:created_at.gt => created_at).asc(:created_at).first @comments = @post.comments end - - private - def map - { - "life"=> "生活", - "tech"=> "技术", - "creator"=> "创业" - } - end end diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 1ff0363..840f8d5 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -23,10 +23,6 @@ class CommentsController < ApplicationController params.permit(:content, :name, :email) end - def format_time(time) - time.strftime("%Y-%m-%d %H:%M") - end - def build_json(comment) { content: comment.content, diff --git a/app/models/post.rb b/app/models/post.rb index dccbc22..25370f5 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -37,4 +37,8 @@ class Post def sub_content HTML_Truncator.truncate(content_html,100) end + + def labels_content + self.labels.collect { |label| label.name }.join(", ") + end end diff --git a/app/views/archives/index.html.slim b/app/views/archives/index.html.slim index 5402cb6..8c96092 100644 --- a/app/views/archives/index.html.slim +++ b/app/views/archives/index.html.slim @@ -1,19 +1,28 @@ -.row +.row ng-controller="ArchivesController" .small-12.large-8.columns ul.archives-field - - 3.times do - li - a.blog-title href="#" 科学是什么 - p.tags-field - i.fi-calendar - span 2014-2-12 - i.fi-list - span 技术 - i.fi-pricetag-multiple - span 生活, 感悟 - i.fi-torsos - span 1010 - i.fi-heart - span 10 + li ng-repeat=" post in posts " + a.blog-title ng-click="visit(post.id)" + |{{ post.title }} + p.tags-field + i.fi-calendar + span + |{{ post.created_at }} + i.fi-list + span + |{{ post.type }} + i.fi-pricetag-multiple + span + |{{ post.labels }} + i.fi-torsos + span + |{{ post.visited_count }} + i.fi-heart + span + |{{ post.liked_count }} + .no-more-field + p ng-show="no_more_flag" 没有更多内容 + .load-more - button.small Load More + button.small ng-click="load()" ng-show="!loading_flag" Load More + button.small ng-show="loading_flag" Loading diff --git a/spec/controllers/archives_controller_spec.rb b/spec/controllers/archives_controller_spec.rb index 92853ce..04842bc 100644 --- a/spec/controllers/archives_controller_spec.rb +++ b/spec/controllers/archives_controller_spec.rb @@ -2,10 +2,47 @@ require 'spec_helper' describe ArchivesController do + def posts_data(response) + JSON.parse(response.body)["posts"] + end + describe "GET 'index'" do - it "returns http success" do - get 'index' - response.should be_success + it "json" do + get 'index', format: :json + posts_data(response).size.should == 0 + end + + it "add ten" do + posts = create_list(:post_list, 10) + get 'index', format: :json + posts_data(response).size.should == 10 + end + + it "add 20" do + posts = create_list(:post_list, 20) + get 'index', format: :json + posts_data(response).size.should == 10 + end + + it "type filter" do + posts = create_list(:post_list, 20) + life_posts = create_list(:post_list, 5, type: Post::LIFE) + get 'index', type: 'life', format: :json + posts_data(response).size.should == 5 + end + + it "start_with filter" do + posts = create_list(:post_list, 10) + start_with = posts[4].created_at.to_i.to_s + get 'index', start_with: start_with, format: :json + posts_data(response).size.should == 5 + end + + it "load_more" do + posts = create_list(:post_list, 20) + get 'index', format: :json + start_with = JSON.parse(response.body)['start_with'] + expect(start_with).to eq( posts[9].created_at.to_i.to_s ) end end diff --git a/spec/controllers/blogs_controller_spec.rb b/spec/controllers/blogs_controller_spec.rb index 5574f85..41c3c3d 100644 --- a/spec/controllers/blogs_controller_spec.rb +++ b/spec/controllers/blogs_controller_spec.rb @@ -61,4 +61,27 @@ describe BlogsController do assigns[:comments][1].content.should == 'iloveyou' assigns[:comments][1].email.should == 'liuzhen@.com' end + + describe "get SHOW" do + it "#prev, #next" do + posts = create_list(:post_list, 3) + selected = posts[1] + s_prev = posts[0] + s_next = posts[2] + get :show, id: selected.id + expect(assigns(:prev)).to eq(s_prev) + expect(assigns(:next)).to eq(s_next) + + selected = posts[0] + get :show, id: selected.id + expect(assigns(:prev)).to be_nil + expect(assigns(:next)).to eq(posts[1]) + + selected = posts[2] + get :show, id: selected.id + expect(assigns(:prev)).to eq(posts[1]) + expect(assigns(:next)).to be_nil + + end + end end diff --git a/spec/factories/comments.rb b/spec/factories/comments.rb new file mode 100644 index 0000000..58a5ae2 --- /dev/null +++ b/spec/factories/comments.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :comment do + content 'content' * 10 + type Post::TECH + association :post + end +end diff --git a/spec/factories/posts.rb b/spec/factories/posts.rb new file mode 100644 index 0000000..c31d750 --- /dev/null +++ b/spec/factories/posts.rb @@ -0,0 +1,14 @@ +FactoryGirl.define do + factory :post do + title 'this is a post title' + content 'content' * 10 + type Post::TECH + end + + factory :post_list, class: Post do + sequence(:title) { |n| "#{n}: post title" } + content 'content' * 10 + sequence(:created_at) { |n| n.days.ago } + type Post::TECH + end +end diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb index 1907dd1..ca5e54f 100644 --- a/spec/models/post_spec.rb +++ b/spec/models/post_spec.rb @@ -2,7 +2,6 @@ require 'spec_helper' describe Post do it "validates should be ok" do - a = Post.create!(title: 'one', content: '1'*31, type: Post::TECH ) - a.save.should == true + expect(create(:post)).to be_true end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index fb22659..0906c7f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -9,11 +9,7 @@ require 'rspec/autorun' Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} RSpec.configure do |config| - # ## Mock Framework - # - # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: - # clear test data - + config.include FactoryGirl::Syntax::Methods config.before :each do DatabaseCleaner.strategy = :truncation DatabaseCleaner.start @@ -23,22 +19,6 @@ RSpec.configure do |config| DatabaseCleaner.clean end - # - # config.mock_with :mocha - # config.mock_with :flexmock - # config.mock_with :rr config.mock_with :rspec - - # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures - #config.fixture_path = "#{::Rails.root}/spec/fixtures" - - # If you're not using ActiveRecord, or you'd prefer not to run each of your - # examples within a transaction, remove the following line or assign false - # instead of true. - #config.use_transactional_fixtures = true - - # If true, the base class of anonymous controllers will be inferred - # automatically. This will be the default behavior in future versions of - # rspec-rails. config.infer_base_class_for_anonymous_controllers = false end