From 08b7b729091643f87ad33de892ed64078c601189 Mon Sep 17 00:00:00 2001 From: HuangQi <1321694949@qq.com> Date: Tue, 5 Jan 2016 18:28:51 +0800 Subject: [PATCH] rails --- Gemfile | 10 +-- Gemfile.lock | 4 +- Gemfile~ | 73 ++++++++++++++++++++++ app/controllers/articles_controller.rb | 69 +++++++++++++++++--- app/controllers/articles_controller.rb~ | 83 +++++++++++++++++++++++++ app/models/article.rb | 15 +++++ app/models/article.rb~ | 16 +++++ app/views/articles/_error.html.haml | 11 ++++ app/views/articles/_error.html.haml~ | 0 app/views/articles/_form.html.haml | 39 ++++++++++++ app/views/articles/_form.html.haml~ | 0 app/views/articles/edit.html.haml | 3 + app/views/articles/edit.html.haml~ | 0 app/views/articles/index.html.haml | 26 ++++++++ app/views/articles/index.html.haml~ | 0 app/views/articles/index.js.haml | 2 + app/views/articles/index.js.haml~ | 0 app/views/articles/new.html.haml | 4 ++ app/views/articles/new.html.haml~ | 0 app/views/articles/show.html.haml | 57 +++++++++++++++++ app/views/articles/show.html.haml~ | 0 app/views/articles/show.js.haml | 2 + app/views/articles/show.js.haml~ | 0 config/initializers/secret_token.rb~ | 1 + config/secrets.yml.example | 22 +++++++ config/secrets.yml.example~ | 22 +++++++ 26 files changed, 445 insertions(+), 14 deletions(-) create mode 100644 Gemfile~ create mode 100644 app/controllers/articles_controller.rb~ create mode 100644 app/models/article.rb~ create mode 100644 app/views/articles/_error.html.haml create mode 100644 app/views/articles/_error.html.haml~ create mode 100644 app/views/articles/_form.html.haml create mode 100644 app/views/articles/_form.html.haml~ create mode 100644 app/views/articles/edit.html.haml create mode 100644 app/views/articles/edit.html.haml~ create mode 100644 app/views/articles/index.html.haml create mode 100644 app/views/articles/index.html.haml~ create mode 100644 app/views/articles/index.js.haml create mode 100644 app/views/articles/index.js.haml~ create mode 100644 app/views/articles/new.html.haml create mode 100644 app/views/articles/new.html.haml~ create mode 100644 app/views/articles/show.html.haml create mode 100644 app/views/articles/show.html.haml~ create mode 100644 app/views/articles/show.js.haml create mode 100644 app/views/articles/show.js.haml~ create mode 100644 config/initializers/secret_token.rb~ create mode 100755 config/secrets.yml.example create mode 100755 config/secrets.yml.example~ diff --git a/Gemfile b/Gemfile index a016443..eb2ee12 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,4 @@ -source 'https://rubygems.org' +source 'https://ruby.taobao.org' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' @@ -26,7 +26,7 @@ gem 'settingslogic' # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks gem 'turbolinks' # Use jquery as the JavaScript library -gem 'jquery-rails' +#gem 'jquery-rails' # 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. @@ -38,9 +38,9 @@ gem 'bootstrap-sass' gem 'font-awesome-sass-rails', '~> 3.0.2.2' gem 'twitter-bootstrap-rails-confirm', github: 'fxhover/twitter-bootstrap-rails-confirm', branch: 'bootstrap3' # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks -gem 'turbolinks' +#gem 'turbolinks' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder -gem 'jbuilder', '~> 2.0' +#gem 'jbuilder', '~> 2.0' # Use ActiveModel has_secure_password gem 'bcrypt', '~> 3.1.7' # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring @@ -68,6 +68,6 @@ group :development, :test do 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 'spring' + #gem 'spring' end diff --git a/Gemfile.lock b/Gemfile.lock index b911a38..cf09355 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -12,7 +12,7 @@ GIT markdown-toolbar (1.0.1) GEM - remote: https://rubygems.org/ + remote: https://ruby.taobao.org/ specs: actionmailer (4.2.3) actionpack (= 4.2.3) @@ -227,4 +227,4 @@ DEPENDENCIES web-console (~> 2.0) BUNDLED WITH - 1.10.6 + 1.11.2 diff --git a/Gemfile~ b/Gemfile~ new file mode 100644 index 0000000..037fd28 --- /dev/null +++ b/Gemfile~ @@ -0,0 +1,73 @@ +source 'https://ruby.taobao.org' + + +# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' +gem 'rails', '4.2.3' +# Use mysql as the database for Active Record +gem 'mysql2' +# Use sqlite3 as the database for Active Record +gem 'sqlite3' +# 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 +# See https://github.com/sstephenson/execjs#readme for more supported runtimes +gem 'therubyracer', platforms: :ruby +# Use jquery as the JavaScript library +gem 'jquery-rails' +#Use kaminari page +gem 'kaminari' +#Use settingslogic +gem 'settingslogic' +# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks +gem 'turbolinks' +# Use jquery as the JavaScript library +#gem 'jquery-rails' +# 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 haml template +gem 'haml-rails' +# Use bootstrap css +gem 'bootstrap-sass' +gem 'font-awesome-sass-rails', '~> 3.0.2.2' +gem 'twitter-bootstrap-rails-confirm', github: 'fxhover/twitter-bootstrap-rails-confirm', branch: 'bootstrap3' +# 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' +# Use ActiveModel has_secure_password +gem 'bcrypt', '~> 3.1.7' +# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring +gem 'spring', group: :development +# Use Unicorn as the app server +# gem 'unicorn' + +# Use Capistrano for deployment +# gem 'capistrano-rails', group: :development +group :development do + gem 'thin' +end +#Avatar +gem 'gravatar_image_tag' +#markdown +gem 'markdown-toolbar', git: 'https://github.com/fuksito/markdown-toolbar.git' +gem 'redcarpet' +gem 'simple_fileupload' +gem 'remotipart' +group :development, :test do + # Call 'byebug' anywhere in the code to stop execution and get a debugger console + gem 'byebug' + + # 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 'spring' +end + diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb index c6ec916..0998550 100644 --- a/app/controllers/articles_controller.rb +++ b/app/controllers/articles_controller.rb @@ -1,19 +1,58 @@ class ArticlesController < ApplicationController def index - + res = Article + order = 'updated_at desc' + if params[:sort].present? + order = case params[:sort] + when 'star' + 'star_count desc' + when 'comments' + 'comments_count desc' + else + 'updated_at desc' + end + end + if params[:c].present? + category = Category.find params[:c] + res = res.where("category_id=#{category.id}") if category + end + res = res.where("title like ?", "%#{params[:keyword]}%") if params[:keyword].present? + @articles = res.order(order).page(params[:page]).per(Settings.blog.aritcle_page_size) + respond_to do |format| + format.html + format.js + end end def new - + @article = Article.new end def create - + @article = Article.new params.require(:article).permit(:title, :tags, :source, :content) + @article.user_id = @current_user.id + if params[:article].present? && params[:article][:category_id].present? + @article.category_id = params[:article][:category_id] + elsif params[:article].present? && params[:article][:category_name].present? + category = Category.find_or_create params[:article][:category_name] + @article.category_id = category.id + end + if @article.save + redirect_to article_path(@article) + else + render 'new' + end end def show - + @article.add_view request.remote_ip, @current_user, params.inspect + @comment = @article.comments.new + @comments = @article.comments.order('updated_at asc').page(params[:page]).per(Settings.blog.comments_page_size) + respond_to do |format| + format.html + format.js + end end def edit @@ -21,11 +60,27 @@ class ArticlesController < ApplicationController end def update - + attributes = params.require(:article).permit(:title, :tags, :source, :content) + if params[:article].present? && params[:article][:category_id].present? + attributes[:category_id] = params[:article][:category_id] + elsif params[:article].present? && params[:article][:category_name].present? + category = Category.find_or_create params[:article][:category_name] + attributes[:category_id] = category.id + end + if @article.update_attributes attributes + redirect_to article_path(@article) + else + render 'edit' + end end def destroy - + if @article.destroy + redirect_to articles_path + else + flash[:error] = '删除失败' + redirect_to article_path(@article) + end end def star @@ -41,4 +96,4 @@ class ArticlesController < ApplicationController def article end -end \ No newline at end of file +end diff --git a/app/controllers/articles_controller.rb~ b/app/controllers/articles_controller.rb~ new file mode 100644 index 0000000..a818945 --- /dev/null +++ b/app/controllers/articles_controller.rb~ @@ -0,0 +1,83 @@ +class ArticlesController < ApplicationController + + def index + res = Article + order = 'updated_at desc' + if params[:sort].present? + order = case params[:sort] + when 'star' + 'star_count desc' + when 'comments' + 'comments_count desc' + else + 'updated_at desc' + end + end + if params[:c].present? + category = Category.find params[:c] + res = res.where("category_id=#{category.id}") if category + end + res = res.where("title like ?", "%#{params[:keyword]}%") if params[:keyword].present? + @articles = res.order(order).page(params[:page]).per(Settings.blog.aritcle_page_size) + respond_to do |format| + format.html + format.js + end + end + + def new + @article = Article.new + end + + def create + @article = Article.new params.require(:article).permit(:title, :tags, :source, :content) + @article.user_id = @current_user.id + if params[:article].present? && params[:article][:category_id].present? + @article.category_id = params[:article][:category_id] + elsif params[:article].present? && params[:article][:category_name].present? + category = Category.find_or_create params[:article][:category_name] + @article.category_id = category.id + end + if @article.save + redirect_to article_path(@article) + else + render 'new' + end + end + + def show + @article.add_view request.remote_ip, @current_user, params.inspect + @comment = @article.comments.new + @comments = @article.comments.order('updated_at asc').page(params[:page]).per(Settings.blog.comments_page_size) + respond_to do |format| + format.html + format.js + end + end + + def edit + + end + + def update + + end + + def destroy + + end + + def star + + end + + protected + + def check_current_user_is_admin + + end + + def article + + end +end diff --git a/app/models/article.rb b/app/models/article.rb index 30a9d9e..7346b1d 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -12,5 +12,20 @@ class Article < ActiveRecord::Base validates :content, length: {minimum: 10} validate :validate_category + def validate_category + errors.add(:category_id, '分类不正确') unless Category.find(self.category_id) + rescue + errors.add(:category_id, '分类不正确') + return false + else + return true + end + + def add_view(ip, current_user, param_string) + return false if (self.article_views.where("created_at >= '#{DateTime.now - 10.minute}' and ip='#{ip}'").count > 0) + view = self.article_views.new ip: ip, param_string: param_string + view.user_id = current_user.id if current_user + view.save + end end diff --git a/app/models/article.rb~ b/app/models/article.rb~ new file mode 100644 index 0000000..30a9d9e --- /dev/null +++ b/app/models/article.rb~ @@ -0,0 +1,16 @@ +class Article < ActiveRecord::Base + attr_accessor :category_name + belongs_to :category, counter_cache: 'articles_count' + belongs_to :user + has_many :article_stars + has_many :article_views + has_many :comments, class_name: 'ArticleComment' + + validates :title, length: {minimum: 10, maximum: 50} + validates :tags, presence: true + validates :source, allow_blank: true, format: {with: /[a-zA-Z0-9-]+\.[a-zA-Z0-9]+/} + validates :content, length: {minimum: 10} + + validate :validate_category + +end diff --git a/app/views/articles/_error.html.haml b/app/views/articles/_error.html.haml new file mode 100644 index 0000000..4f1317e --- /dev/null +++ b/app/views/articles/_error.html.haml @@ -0,0 +1,11 @@ +- errors = @article.errors.full_messages +- if errors.any? + .alert.alert-danger + %a.close{"data-dismiss"=>"alert"} × + %span + = errors.first +- elsif flash[:error].present? + .alert.alert-danger + %a.close{"data-dismiss"=>"alert"} × + %span + = flash[:error] diff --git a/app/views/articles/_error.html.haml~ b/app/views/articles/_error.html.haml~ new file mode 100644 index 0000000..e69de29 diff --git a/app/views/articles/_form.html.haml b/app/views/articles/_form.html.haml new file mode 100644 index 0000000..af7670d --- /dev/null +++ b/app/views/articles/_form.html.haml @@ -0,0 +1,39 @@ += render partial: 'toolbar_upload_img', locals: {text_id: 'article_content'} + += form_for @article, role: 'form' do |f| + .form-group + %label{for: 'article_title'} 文章标题 + = f.text_field :title, placeholder: '文章标题', class: 'form-control' + .form-group + %label{for: 'article_category_id'} 文章分类 + = select_tag "article[category_id]", options_for_select(get_categories_options, @article.category_id), include_blank: true, class: 'form-control' + 或者新建一个分类: + = f.text_field :category_name, placeholder: '分类名称', class: 'form-control' + .form-group + %label{for: 'article_tags'} 标签 + = f.text_field :tags, placeholder: '文章标签,多个用英文“,”隔开', class: 'form-control' + .form-group + %label{for: 'article_source'} 文章来源 + = f.text_field :source, placeholder: '文章来源,为空则为原创', class: 'form-control' + .form-group + %ul.nav.nav-tabs#preview_tab{role: "tablist"} + %li.active + = link_to '文章内容', '#edit', role: 'tab', 'data-toggle'=>'tab' + %li + = link_to '预览', '#preview', role: 'tab', 'data-toggle'=>'tab' + .tab-content + .tab-pane.active#edit + = f.text_area :content, placeholder: '文章内容', class: 'form-control' + .tab-pane#preview + .form-group + = f.submit '提交', class: 'btn btn-success btn-lg btn-block' + +:javascript + $(function(){ + $('#preview_tab a[href="#preview"]').click(function(e){ + e.preventDefault(); + $(this).tab('show'); + preview('article_content', 'preview'); + }); + }); + diff --git a/app/views/articles/_form.html.haml~ b/app/views/articles/_form.html.haml~ new file mode 100644 index 0000000..e69de29 diff --git a/app/views/articles/edit.html.haml b/app/views/articles/edit.html.haml new file mode 100644 index 0000000..8323d39 --- /dev/null +++ b/app/views/articles/edit.html.haml @@ -0,0 +1,3 @@ +%h3 编辑博文 += render partial: 'error' += render partial: 'form' diff --git a/app/views/articles/edit.html.haml~ b/app/views/articles/edit.html.haml~ new file mode 100644 index 0000000..e69de29 diff --git a/app/views/articles/index.html.haml b/app/views/articles/index.html.haml new file mode 100644 index 0000000..fec4c28 --- /dev/null +++ b/app/views/articles/index.html.haml @@ -0,0 +1,26 @@ +.row.inner.edge + .col-md-9.layout-main + .tab-nav + -# %h2.common-title 博文列表 + %nav.sub-tab.row + %span.col-md-6.text-left + %h3 文章列表 + %span.col-md-6.text-right.sort_navbar + - params_hash = params.dup + - params_hash.delete :page + %span.icon.icon-circle-arrow-down(data-toggle="tooltip" data-placement="bottom" title="排序") + = link_to '按时间', articles_path(params_hash.merge({sort: 'time'})), remote: true, class: "#{'current' if params[:sort].nil? || params[:sort] == 'time'}" + = link_to '按称赞', articles_path(params_hash.merge({sort: 'star'})), remote: true, class: "#{'current' if params[:sort].present? && params[:sort] == 'star'}" + = link_to '按评论', articles_path(params_hash.merge({sort: 'comments'})), remote: true, class: "#{'current' if params[:sort].present? && params[:sort] == 'comments'}" + .article-list#article-list + = render partial: 'articles' + + .sidebar.col-md-3.layout-secondary.hidden-xs.hidden-sm + = render partial: 'article_sidebar' + +:javascript + $(function(){ + $('.sort_navbar a').click(function(){ + $(this).addClass('current').siblings().removeClass('current'); + }); + }); diff --git a/app/views/articles/index.html.haml~ b/app/views/articles/index.html.haml~ new file mode 100644 index 0000000..e69de29 diff --git a/app/views/articles/index.js.haml b/app/views/articles/index.js.haml new file mode 100644 index 0000000..5007459 --- /dev/null +++ b/app/views/articles/index.js.haml @@ -0,0 +1,2 @@ +:plain + $('#article-list').html("#{escape_javascript(render partial: 'articles')}"); diff --git a/app/views/articles/index.js.haml~ b/app/views/articles/index.js.haml~ new file mode 100644 index 0000000..e69de29 diff --git a/app/views/articles/new.html.haml b/app/views/articles/new.html.haml new file mode 100644 index 0000000..c56fbe7 --- /dev/null +++ b/app/views/articles/new.html.haml @@ -0,0 +1,4 @@ + +%h3 撰写博文 += render partial: 'error' += render partial: 'form' diff --git a/app/views/articles/new.html.haml~ b/app/views/articles/new.html.haml~ new file mode 100644 index 0000000..e69de29 diff --git a/app/views/articles/show.html.haml b/app/views/articles/show.html.haml new file mode 100644 index 0000000..5b48000 --- /dev/null +++ b/app/views/articles/show.html.haml @@ -0,0 +1,57 @@ +.article_show + = render partial: 'error' + %h3.article-title + - if @article.source.empty? + [原创] + = @article.title + - if current_user_is_admin? + = link_to edit_article_path(@article) do + %span.icon.icon-edit + = link_to article_path(@article), method: 'delete', "data-confirm"=> "确定删除吗?" do + %span.icon.icon-trash + + + %p + - get_tags(@article).each do |tag| + %span.label.label-default + = tag + %p + %span.icon + 分类: + = link_to @article.category.name, articles_path(c: @article.category_id) + %span.icon.icon-time(data-toggle="tooltip" data-placement="bottom" title="发表时间") + = @article.updated_at.strftime('%Y-%m-%d %H:%M') + %span.icon.icon-eye-open(data-toggle="tooltip" data-placement="bottom" title="浏览") + = @article.view_count || 1 + - if current_user_can_star?(@article) + = link_to star_article_path(@article), method: :post, remote: 'true' do + %span.icon.icon-thumbs-up#article_star(data-toggle="tooltip" data-placement="bottom" title="称赞") + = @article.star_count || 0 + - else + %span.icon.icon-thumbs-up(data-toggle="tooltip" data-placement="bottom" title="称赞数") + = @article.star_count || 0 + %span.icon.icon-comments(data-toggle="tooltip" data-placement="bottom" title="评论") + = @article.comments_count || 0 + - unless @article.source.empty? + %p + 转载: + = @article.source + + .panel.panel-dfault + .panel-body + %p + = raw markdown_parser(@article.content) + + %h3 评论: + #comments_content + = render partial: 'comments' + + - if is_logined? + #comment_form + = render partial: 'comment_form' + - else + .jumbotron + %h2 + = link_to '登录', login_path + 后可评论 + diff --git a/app/views/articles/show.html.haml~ b/app/views/articles/show.html.haml~ new file mode 100644 index 0000000..e69de29 diff --git a/app/views/articles/show.js.haml b/app/views/articles/show.js.haml new file mode 100644 index 0000000..3672e74 --- /dev/null +++ b/app/views/articles/show.js.haml @@ -0,0 +1,2 @@ +:plain + $('#comments_content').html("#{escape_javascript(render partial: 'comments')}"); diff --git a/app/views/articles/show.js.haml~ b/app/views/articles/show.js.haml~ new file mode 100644 index 0000000..e69de29 diff --git a/config/initializers/secret_token.rb~ b/config/initializers/secret_token.rb~ new file mode 100644 index 0000000..41b0303 --- /dev/null +++ b/config/initializers/secret_token.rb~ @@ -0,0 +1 @@ +6a220677438f874ca75763b1525ada21139d0f3a30f25b929d33222bef3bd8a0368bc03e87d1b495e2aedd297398bf470c693318bed3c72a27be5b31725aab0b diff --git a/config/secrets.yml.example b/config/secrets.yml.example new file mode 100755 index 0000000..633c51c --- /dev/null +++ b/config/secrets.yml.example @@ -0,0 +1,22 @@ +# Be sure to restart your server when you modify this file. + +# Your secret key is used for verifying the integrity of signed cookies. +# If you change this key, all old signed cookies will become invalid! + +# Make sure the secret is at least 30 characters and all random, +# no regular words or you'll be exposed to dictionary attacks. +# You can use `rake secret` to generate a secure secret key. + +# Make sure the secrets in this file are kept private +# if you're sharing your code publicly. + +development: + secret_key_base: eef518ad815fbd36abb4a59e5ef6316f4ba52c1108b7bd78682354174108979016f101eecfcd2d6b6543a7b5795e73b17c4fc27d69146dd864445b6e6a0bfd08 + +test: + secret_key_base: 38e245a613b00c6701f3525867eb0c2e0b9d8f1395d54a2d7a3c1e3f35480fa331272f5cf1a74a130a60ed922131a00851c09a5819330652cd73e85378d0ca0a + +# Do not keep production secrets in the repository, +# instead read values from the environment. +production: + secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> diff --git a/config/secrets.yml.example~ b/config/secrets.yml.example~ new file mode 100755 index 0000000..0cf7d00 --- /dev/null +++ b/config/secrets.yml.example~ @@ -0,0 +1,22 @@ +# Be sure to restart your server when you modify this file. + +# Your secret key is used for verifying the integrity of signed cookies. +# If you change this key, all old signed cookies will become invalid! + +# Make sure the secret is at least 30 characters and all random, +# no regular words or you'll be exposed to dictionary attacks. +# You can use `rake secret` to generate a secure secret key. + +# Make sure the secrets in this file are kept private +# if you're sharing your code publicly. + +development: + secret_key_base: 6938efe794286cdef1a2929153f78aa17f3005ab4e671e0ba21bf09057b448152f1725ca939d77d392bec467487e40e4d7e9e9ed9ba785e746e80c5dea106e0e + +test: + secret_key_base: 38e245a613b00c6701f3525867eb0c2e0b9d8f1395d54a2d7a3c1e3f35480fa331272f5cf1a74a130a60ed922131a00851c09a5819330652cd73e85378d0ca0a + +# Do not keep production secrets in the repository, +# instead read values from the environment. +production: + secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>