ITニュース専用の掲示板「89channel」を開発したときの記録
今日、ITニュースにコメントし合える掲示板サービス「89channel」をリリースしました。 Hack Channelと読みます。 ただのシャレです(´・ω・`)
この開発についてまとめてみました。
89channelとは
89channelは、今話題のITニュースにコメントで議論できる掲示板サービスです。 Hacker Newsの日本版を目指してつくりました。 サービスの使い方についてはAboutをご覧ください。
Hacker Newsはユーザが記事をsubmitできますが、今回最初からこの機能をつけるとスパムの温床になるかなと危惧しました。 なので、現状は既存リソースから記事を定期取得するようしています。
今回、開発期間はrails new
から10日間でのリリースでした。
開発環境
今回はRailsでサービスをつくりたかったので、Railsを採用しました。 Gemfileは記事のおわりにありますので、よかったら見てください。
- Ruby on Rails 4.1.1
- MySQL 5.6.19
- Haml/SCSS/CoffeeScript
- nginx/Unicorn
- Capistrano v3
- RSpec/Capybara(Poltergeist)/FactoryGirl
- Chef Solo
- Jenkins
開発ログ
権限管理はCanCanCanで
権限管理に、前から使ってみたかったCanCanを導入しました。 ただ、これはメンテナンスされておらず、Strong Parameters周りでうまく動作しません。
この後継としてCanCanCanがあるということがわかり、問題なく動作したのでこれを使いました。
デバッグ環境は超大事
これまで開発してきたサービスは、恥ずかしながらbetter_errorsのみを使ってブラウザでデバッグしてました。 今回は、デバッグに以下のgemを使いました。 それぞれの説明は省きますが、開発効率が何十倍になったんだろう……というくらい改善しました。
rails_best_practicesについては、愚直に従うのではなく、根拠を理解した上で、自分なりに採否を決め実装することが大事かなと思います。
group :development do gem 'pry-rails' gem 'pry-byebug' gem 'hirb' gem 'hirb-unicode' gem 'awesome_print' gem 'better_errors' gem 'binding_of_caller' gem 'quiet_assets' gem 'annotate' gem 'bullet' gem 'rails_best_practices' end
文書はMarkdownで
AboutやTerms of Service、Privacy Policy各ページは、内部ではMarkdownで書いています。 これは、RedcarpetをGemfileに書きさえすれば、あとはHamlとして以下のように書けます。
:markdown 本プライバシーポリシー(以下、「本ポリシー」と称します)は、ユーザが89channel(以下、「本サービス」と称します)を利用するにあたり、ユーザの情報を収集、利用する方法について説明するものです。 本サービスを利用する場合、ユーザは、本ポリシーの記載に従い、ユーザ情報が収集、転送、操作、保存、開示およびその他の方法で利用されることに同意するものとします。 ### 1. 情報の収集 - 本サービスにユーザ登録を行なう場合、ユーザ名(任意)とパスワードを入力する必要があります。 - 本サービスは、クッキーおよびこの類似技術を利用しており、本サービスはセッションクッキーおよび永続的なクッキーの両方を利用できるものとします。 - 本サービスでは、ユーザが本サービスを利用することによって作成される情報(ログデータ)が自動的に記録されます。
Wheneverは有能
各記事には、今どれくらいホットかというトレンドポイントを持たせています。 このトレンドポイントは随時計算していると負荷が大きいと思ったので、cronで定期処理しています。 他にも、記事の取得やBackupを用いたバックアップにもcronを使っています。
このcronをRailsから簡単に使うgemがWheneverなのですが、これがまた大変便利です。
以下のようにconfig/schedule.rb
に書くだけで、productionにデプロイ時によしなにやってくれます。
every 1.day, at: '00:00 am', roles: [:db] do rake 'backup:start' end
サーバへのcrontabのインストールは忘れずに!
メンテナンスはCapistrano::Maintenanceで
メンテナンス用gemとして有名なものにTurnoutがあります。
これはRackミドルウェアとして動作し、tmp/maintenance.yml
の有無でメンテナンス中かどうかを判断します。
ただ、Capistranoでデプロイするとcurrent/tmp
下に作られることになり、current/
が指すreleaseディレクトリが変わると訳がわからなくなります。
Capistrano::Maintenanceはnginx側でpublic/
下のファイルを静的に判断するので、運用者に分かりやすい作りなんじゃないかな、と思い採用しました。
turbolinksを無効にした
これは最後まで迷ったのですが、turbolinksを無効にしました。
今回Infinite ScrollとSidrを採用したのですが、これがturbolinksと相性が悪いです。 具体的には、たとえば一度Infinite Scrollが発火すると、ページを遷移しても延々と裏でSQLを発行してしまいます。 恐ろしい……。
jQuery Turbolinksを入れても解決しなかったので、turbolinksを無効にしました。
おわりに
個人でサービスをつくるのはこれで4つ目になるのですが、自分の中での技術的なブレークスルーがあまりありませんでした。 複数人でサービスをつくってみたいのですが、無職なので難しいです。 次はマンネリを打破するためにNode.jsでサービスをつくってみます。
ご意見などあればTwitterまで連絡ください! お待ちしております。
おまけ:Gemfile
特にこれといったものは使っていませんが、公開してみます。
source 'https://rubygems.org' gem 'rails', '4.1.1' gem 'mysql2' gem 'haml-rails' gem 'sass-rails' gem 'coffee-rails' gem 'jquery-rails' gem 'jbuilder' gem 'uglifier' gem 'bcrypt' gem 'cancancan' # 権限管理 gem 'redcarpet' # Markdown パーサ gem 'kaminari' # ページング gem 'paranoia' # ユーザの論理削除 gem 'whenever' # cron 処理 gem 'backup' # MySQL のバックアップ group :development do gem 'spring' # プリローダ(開発コマンド高速化) gem 'spring-commands-rspec' # bin/rspec を生成 gem 'capistrano' # デプロイ gem 'capistrano-rails' gem 'capistrano-maintenance', github: 'capistrano/maintenance', require: false # メンテナンス画面(要 nginx 設定) gem 'erb2haml' # .erb を .haml に変換 gem 'pry-rails' # rails c を pry にする gem 'pry-byebug' # ブレークポイントがつかえる gem 'hirb' # コンソール出力を整形する gem 'hirb-unicode' # hirb のユニコード対応 gem 'awesome_print' # デバッグ出力を整形する ap コマンドを追加 gem 'better_errors' # エラー画面を見やすく表示 gem 'binding_of_caller' # エラー画面で REPL が使える gem 'quiet_assets' # ログを整形 gem 'annotate' # model にスキーマ情報を付加 gem 'bullet' # N+1 問題を検知 gem 'rails_best_practices' # コードチェック end group :development, :test do gem 'rspec-rails' gem 'capybara' gem 'poltergeist' gem 'factory_girl' gem 'database_cleaner' gem 'shoulda-matchers', require: false # RSpecにマッチャを追加 end group :production do gem 'therubyracer' gem 'unicorn' end