Commit 35a3b5a2 by tady

Merge pull request #85 from tadyjp/140430/flow-view

[WIP] 140430/flow view
parents ad76c651 5baafc38
...@@ -32,3 +32,4 @@ ...@@ -32,3 +32,4 @@
/script/backup.sh /script/backup.sh
.rbenv-gemsets .rbenv-gemsets
.ruby-version
source 'https://rubygems.org' source 'https://rubygems.org'
ruby '2.0.0'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 4' gem 'rails', '~> 4'
......
...@@ -16,7 +16,7 @@ guard :rspec do ...@@ -16,7 +16,7 @@ guard :rspec do
watch(%r{^spec/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' } watch(%r{^spec/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
end end
guard :teaspoon do # guard :teaspoon do
watch(%r{^app/assets/javascripts/(.+).js}) { |m| "spec/javascripts/#{m[1]}_spec.js.coffee" } # watch(%r{^app/assets/javascripts/(.+).js}) { |m| "spec/javascripts/#{m[1]}_spec.js.coffee" }
watch(%r{^spec/javascripts/(.*)}) # watch(%r{^spec/javascripts/(.*)})
end # end
...@@ -5,7 +5,9 @@ class ApplicationController < ActionController::Base ...@@ -5,7 +5,9 @@ class ApplicationController < ActionController::Base
add_breadcrumb("Rendezvous", '/') add_breadcrumb("Rendezvous", '/')
def require_login before_action :redirect_unless_signed_in
def redirect_unless_signed_in
unless user_signed_in? unless user_signed_in?
flash[:alert] = 'You need Login!' flash[:alert] = 'You need Login!'
session[:login_redirect_to] = request.url session[:login_redirect_to] = request.url
......
class FlowController < ApplicationController class FlowController < ApplicationController
before_action :require_login
def show def show
@posts = Post.includes(:tags, :author).where(is_draft: false).order(updated_at: :desc).limit(20).decorate @posts = Post.includes(:tags, :author).where(is_draft: false).order(updated_at: :desc).limit(20).decorate
......
...@@ -2,20 +2,9 @@ require 'nkf' ...@@ -2,20 +2,9 @@ require 'nkf'
class PostsController < ApplicationController class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy, :slideshow] before_action :set_post, only: [:show, :edit, :update, :destroy, :slideshow]
before_action :require_login
include RV::Mailer include RV::Mailer
# GET /posts
# GET /posts.json
def index
if params[:q].present?
@posts = Post.search(params[:q]).limit(10)
else
@posts = Post.order(updated_at: :desc).limit(10)
end
end
# GET /posts/1 # GET /posts/1
# GET /posts/1.json # GET /posts/1.json
def show def show
...@@ -23,12 +12,6 @@ class PostsController < ApplicationController ...@@ -23,12 +12,6 @@ class PostsController < ApplicationController
add_breadcrumb("##{_tag.name}", _tag.decorate.show_path) add_breadcrumb("##{_tag.name}", _tag.decorate.show_path)
end end
add_breadcrumb(@post.title) add_breadcrumb(@post.title)
if params[:fragment].present?
render layout: false, partial: 'posts/show_fragment'
else
render
end
end end
# GET /posts/new # GET /posts/new
...@@ -67,7 +50,7 @@ class PostsController < ApplicationController ...@@ -67,7 +50,7 @@ class PostsController < ApplicationController
respond_to do |format| respond_to do |format|
if @post.save if @post.save
format.html { redirect_to root_path(id: @post.id), flash: { notice: 'Post was successfully created.' } } format.html { redirect_to post_path(id: @post.id), flash: { notice: 'Post was successfully created.' } }
format.json { render action: 'show', status: :created, location: @post } format.json { render action: 'show', status: :created, location: @post }
else else
format.html { render action: 'new' } format.html { render action: 'new' }
...@@ -83,7 +66,7 @@ class PostsController < ApplicationController ...@@ -83,7 +66,7 @@ class PostsController < ApplicationController
respond_to do |format| respond_to do |format|
if @post.update(post_params) if @post.update(post_params)
format.html { redirect_to root_path(id: @post.id), flash: { notice: 'Post was successfully updated.' } } format.html { redirect_to post_path(id: @post.id), flash: { notice: 'Post was successfully updated.' } }
format.json { head :no_content } format.json { head :no_content }
else else
format.html { render action: 'edit' } format.html { render action: 'edit' }
...@@ -108,10 +91,10 @@ class PostsController < ApplicationController ...@@ -108,10 +91,10 @@ class PostsController < ApplicationController
@comment = @post.comments.build(comment_params.merge(author: current_user)) @comment = @post.comments.build(comment_params.merge(author: current_user))
respond_to do |format| respond_to do |format|
if @comment.save if @comment.save
format.html { redirect_to posts_path(id: @post.id) } format.html { redirect_to post_path(id: @post.id) }
format.json { render json: { status: 'ok', comment: @comment }, status: :created } format.json { render json: { status: 'ok', comment: @comment }, status: :created }
else else
format.html { redirect_to posts_path(id: @post.id), flash: { alert: 'Comment is not saved.' } } format.html { redirect_to post_path(id: @post.id), flash: { alert: 'Comment is not saved.' } }
format.json { render json: @comment.errors, status: :unprocessable_entity } format.json { render json: @comment.errors, status: :unprocessable_entity }
end end
end end
......
class SearchController < ApplicationController class SearchController < ApplicationController
before_action :require_login
def show def show
if params[:q].present? if params[:q].present?
......
class StockController < ApplicationController class StockController < ApplicationController
before_action :require_login
def show def show
end end
......
class TagsController < ApplicationController class TagsController < ApplicationController
before_action :set_tag, only: [:show, :edit, :update, :destroy, :merge_to, :move_to, :events] before_action :set_tag, only: [:show, :edit, :update, :destroy, :merge_to, :move_to, :events]
def index
end
def show def show
end end
......
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
skip_before_action :redirect_unless_signed_in
def google_oauth2 def google_oauth2
email = request.env['omniauth.auth'].info['email'] email = request.env['omniauth.auth'].info['email']
......
class WelcomeController < ApplicationController class WelcomeController < ApplicationController
skip_before_action :require_login
skip_before_action :redirect_unless_signed_in
def top def top
if user_signed_in? if user_signed_in?
......
...@@ -29,6 +29,17 @@ class Tag < ActiveRecord::Base ...@@ -29,6 +29,17 @@ class Tag < ActiveRecord::Base
having('posts_count > 0') having('posts_count > 0')
} }
class << self
# 最近投稿されたTagを取得
def recent(limit=10)
Post.recent(20).map do |post|
post.tags
end.flatten.compact.uniq.take(limit)
end
end
def recent_posts(limit = 30) def recent_posts(limit = 30)
self.posts.recent(limit) self.posts.recent(limit)
end end
......
...@@ -20,9 +20,9 @@ ...@@ -20,9 +20,9 @@
.panel.panel-default .panel.panel-default
.panel-heading .panel-heading
h2.panel-title 最近投稿したユーザー(調整中) h2.panel-title 最近投稿されたタグ
.panel-body.list-group .panel-body.list-group
- User.post_recently.limit(10).each_with_index do |author, i| - Tag.recent(10).each_with_index do |tag, i|
a.list-group-item.post-list data-author-id=author.id href=search_path(q: "@#{author.nickname}") = "#{author.name} (@#{author.nickname})" a.list-group-item data-tag-id=tag.id href=search_path(q: "##{tag.name}") = "#{tag.name} (#{tag.posts_count})"
.panel.panel-default
.panel-heading
h3.panel-title
a href=post_path(@post) = @post.title
ul.list-group
li.list-group-item
- @post.tags.each do |tag|
span.label.label-success
a href=tag.decorate.show_path
| ##{tag.name}
| &nbsp;
span.label.label-info
a href=(search_path(q: "@#{@post.author.name}"))
| @#{@post.author.name}
| &nbsp;
span.label.label-danger
a href=(search_path(q: "date:#{@post.display_date}")) = @post.display_date
.btn-group.pull-right style=("margin: -7px -12px 0 0;")
a.btn.btn-primary href=edit_post_path(@post)
span.glyphicon.glyphicon-pencil
button.btn.btn-default.dropdown-toggle data-toggle="dropdown" type="button"
span.caret
span.sr-only Toggle Dropdown
ul.dropdown-menu role="menu"
li
a href=slideshow_post_path(@post) target="_blank" Slideshow
li
a.small href="https://github.com/gnab/remark" target="_blank" What is Slideshow?
li.divider
li
a href=fork_post_path(@post) Fork
li
a data-target="#myModal" data-toggle="modal" href="#" Mail to...
li.divider
li= link_to 'Delete', post_path(@post), method: :delete, data: { confirm: 'Are you sure?' }
.panel-body.viewer.github
= h_application_format_markdown(@post.body)
.panel.panel-success
.panel-heading
h3.panel-title Comments
.panel-body
ul.media-list
- @post.comments.each do |comment|
li.media
a.pull-left href="#"
img.media-object src=comment.author.image_url /
.media-body
h4.media-heading= comment.author.name
= comment.body
= form_tag(comment_post_path, method: :post, data: { 'form-id' => "comment_#{@post.id}" }) do
li.media
a.pull-left href="#"
img.media-object src=current_user.image_url /
.media-body
h4.media-heading= current_user.name
= text_area :comment, :body, class: 'form-control', placeholder: 'コメントする...'
= submit_tag 'Comment', class: 'btn btn-primary', data: { 'disable-with' => '...' }
javascript:
$("form[data-form-id='comment_#{@post.id}']").on('ajax:success', function(event, data, xhr) {
});
/! Button trigger modal
/!
| <button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal"
| Launch demo modal
| </button
/! Modal
#myModal.modal.fade aria-hidden="true" aria-labelledby="myModalLabel" role="dialog" tabindex="-1"
.modal-dialog
.modal-content
= form_tag mail_post_path(@post), method: :post, class: 'form-horizontal', role: 'form' do
.modal-header
button.close aria-hidden="true" data-dismiss="modal" type="button" &times;
h4#myModalLabel.modal-title Mail this post to...
.modal-body
.form-group
label.col-sm-2.control-label Title
.col-sm-10
input.form-control readonly="" type="text" value=@post.title /
.form-group
label.col-sm-2.control-label for="inputEmail3" To
.col-sm-10
input#inputEmail3.form-control name="mail[to]" placeholder="Email" type="email" /
.form-group
label.col-sm-2.control-label From
.col-sm-10
input.form-control readonly="" type="text" value=current_user.email /
.modal-footer
button.btn.btn-default data-dismiss="modal" type="button" Close
button.btn.btn-primary data-disable-with="Sending..." type="submit" Send
/! /.modal-content
/! /.modal-dialog
/! /.modal
= render_breadcrumbs = render_breadcrumbs
.row .row
div .panel.panel-default
= render partial: 'posts/show_fragment' .panel-heading
/! /row h3.panel-title
a href=post_path(@post) = @post.title
ul.list-group
li.list-group-item
- @post.tags.each do |tag|
span.label.label-success
a href=tag.decorate.show_path
| ##{tag.name}
| &nbsp;
span.label.label-info
a href=(search_path(q: "@#{@post.author.name}"))
| @#{@post.author.name}
| &nbsp;
span.label.label-danger
a href=(search_path(q: "date:#{@post.display_date}")) = @post.display_date
.btn-group.pull-right style=("margin: -7px -12px 0 0;")
a.btn.btn-primary href=edit_post_path(@post)
span.glyphicon.glyphicon-pencil
button.btn.btn-default.dropdown-toggle data-toggle="dropdown" type="button"
span.caret
span.sr-only Toggle Dropdown
ul.dropdown-menu role="menu"
li
a href=slideshow_post_path(@post) target="_blank" Slideshow
li
a.small href="https://github.com/gnab/remark" target="_blank" What is Slideshow?
li.divider
li
a href=fork_post_path(@post) Fork
li
a data-target="#myModal" data-toggle="modal" href="#" Mail to...
li.divider
li= link_to 'Delete', post_path(@post), method: :delete, data: { confirm: 'Are you sure?' }
.panel-body.viewer.github
= h_application_format_markdown(@post.body)
.panel.panel-success
.panel-heading
h3.panel-title Comments
.panel-body
ul.media-list
- @post.comments.each do |comment|
li.media
a.pull-left href="#"
img.media-object src=comment.author.image_url /
.media-body
h4.media-heading= comment.author.name
= comment.body
= form_tag(comment_post_path, method: :post, data: { 'form-id' => "comment_#{@post.id}" }) do
li.media
a.pull-left href="#"
img.media-object src=current_user.image_url /
.media-body
h4.media-heading= current_user.name
= text_area :comment, :body, class: 'form-control', placeholder: 'コメントする...'
= submit_tag 'Comment', class: 'btn btn-primary', data: { 'disable-with' => '...' }
javascript:
$("form[data-form-id='comment_#{@post.id}']").on('ajax:success', function(event, data, xhr) {
});
/! Button trigger modal
/!
/! Modal
#myModal.modal.fade aria-hidden="true" aria-labelledby="myModalLabel" role="dialog" tabindex="-1"
.modal-dialog
.modal-content
= form_tag mail_post_path(@post), method: :post, class: 'form-horizontal', role: 'form' do
.modal-header
button.close aria-hidden="true" data-dismiss="modal" type="button" &times;
h4#myModalLabel.modal-title Mail this post to...
.modal-body
.form-group
label.col-sm-2.control-label Title
.col-sm-10
input.form-control readonly="" type="text" value=@post.title /
.form-group
label.col-sm-2.control-label for="inputEmail3" To
.col-sm-10
input#inputEmail3.form-control name="mail[to]" placeholder="Email" type="email" /
.form-group
label.col-sm-2.control-label From
.col-sm-10
input.form-control readonly="" type="text" value=current_user.email /
.modal-footer
button.btn.btn-default data-dismiss="modal" type="button" Close
button.btn.btn-primary data-disable-with="Sending..." type="submit" Send
/! /.modal-content
/! /.modal-dialog
/! /.modal
#! /bin/sh
ssh rendezvous "cd /tmp; mysqldump -urendezvous -pedc08630b029fc979af5fd9e8fd979f690b0be149bac465bd66c2456c8fcd651 rendezvous > rendezvous.`date +'%Y%m%d'`.sql;"; scp rendezvous:/tmp/rendezvous.`date +'%Y%m%d'`.sql ./backup/
...@@ -3,6 +3,7 @@ Rendezvous::Application.routes.draw do ...@@ -3,6 +3,7 @@ Rendezvous::Application.routes.draw do
post 'apis/markdown_preview' post 'apis/markdown_preview'
post 'apis/file_receiver' post 'apis/file_receiver'
get 'apis/user_mention' get 'apis/user_mention'
get 'tags/:name/events' => 'tags#events', as: 'event_tag' get 'tags/:name/events' => 'tags#events', as: 'event_tag'
root 'welcome#top', as: 'root' root 'welcome#top', as: 'root'
...@@ -15,32 +16,17 @@ Rendezvous::Application.routes.draw do ...@@ -15,32 +16,17 @@ Rendezvous::Application.routes.draw do
post 'posts/:id/mail' => 'posts#mail', as: 'mail_post' post 'posts/:id/mail' => 'posts#mail', as: 'mail_post'
post 'posts/:id/comment' => 'posts#comment', as: 'comment_post' post 'posts/:id/comment' => 'posts#comment', as: 'comment_post'
get 'posts/:id/slideshow' => 'posts#slideshow', as: 'slideshow_post' get 'posts/:id/slideshow' => 'posts#slideshow', as: 'slideshow_post'
resources :posts resources :posts, except: [:index]
post 'tags/:name/merge_to/:merge_to_name' => 'tags#merge_to', as: 'merge_to_tag' post 'tags/:name/merge_to/:merge_to_name' => 'tags#merge_to', as: 'merge_to_tag'
post 'tags/:name/move_to/:move_to_name' => 'tags#move_to', as: 'move_to_tag' post 'tags/:name/move_to/:move_to_name' => 'tags#move_to', as: 'move_to_tag'
resources :tags, :param => :name resources :tags, :param => :name, except: [:index]
# resource :user, :only => [:edit, :update]
# devise_for :users , controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
# devise_for :users , only: [:sign_in, :sign_out, :session]
devise_for :users, devise_for :users,
path_names: { current_user: 'me' }, path_names: { current_user: 'me' },
controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' },
skip: [:passwords] skip: [:passwords]
# , controllers: { omniauth_callbacks: 'users/omniauth_callbacks' } # , skip: [:sessions]
# devise_scope :user do
# get 'sign_in', to: 'users/sessions#new', as: :new_user_session
# delete 'sign_out', to: 'devise/sessions#destroy', as: :sign_out
# end
# get 'users/edit' => 'users#edit', as: 'edit_user'
# post 'users/update' => 'users#update', as: 'update_user'
# The priority is based upon order of creation: first created -> highest priority. # The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes". # See how all your routes lay out with "rake routes".
......
# 1行概要
rubyとHTTP通信ライブラリ`faraday`を使ってChatworkの`マイチャット`に投稿するサンプル。
# 犯行動機
ChatはGETできて半人前、POSTできて一人前。
Skypeとか遠距離恋愛で使ってください。エンジニアの使うものではありません。
# 方法
## 1. faradayのインストール (5秒)
``` shell
$ gem install faraday
Successfully installed faraday-0.8.8
Parsing documentation for faraday-0.8.8
Installing ri documentation for faraday-0.8.8
1 gem installed
```
## 2. ChatworkのマイチャットのグループIDを調べる (5秒)
![Screen Shot 2013-12-10 at 11.03.00 PM.png](https://qiita-image-store.s3.amazonaws.com/0/10272/ff3371de-c62f-52bb-2c57-e5649e6d9f2a.png "Screen Shot 2013-12-10 at 11.03.00 PM.png")
## 3. Chatwork APIのトークンを調べる (5秒)
![Screen Shot 2013-12-10 at 11.06.08 PM.png](https://qiita-image-store.s3.amazonaws.com/0/10272/2ada8651-d3a9-9374-11c5-8c014955f948.png "Screen Shot 2013-12-10 at 11.06.08 PM.png")
## 4. 投稿! (15秒)
``` ruby:main.rb
require 'faraday'
ROOM_ID = '<ここに2で取得したマイチャットIDを入れる>' # my chat
CHATWORK_TOKEN = '<ここに3で取得したトークンを入れる>'
conn = Faraday::Connection.new(url: 'https://api.chatwork.com') do |builder|
builder.use Faraday::Request::UrlEncoded
builder.use Faraday::Response::Logger
builder.use Faraday::Adapter::NetHttp
end
response = conn.post do |request|
request.url "/v1/rooms/#{ROOM_ID}/messages"
request.headers = {
'X-ChatWorkToken' => CHATWORK_TOKEN
}
request.params[:body] = "Hello World!" # => ここに入れる文字が投稿される
end
```
そして実行!
```
$ ruby main.rb
```
# 1行概要
rubyのgem anemonを使って指定した正規表現のURLだけクロールし続けるサンプル
# 犯行動機
友人がよからぬ事をしようとしていたので援護射撃
# 方法
```ruby:crawl.rb
require 'anemone'
Anemone.crawl('http://example.com/start_page.html') do |anemone|
# クロールするごとに呼び出される
anemone.focus_crawl do |page|
# 条件に一致するリンクだけ残す
# この `links` はanemoneが次にクロールする候補リスト
page.links.keep_if { |link|
link.to_s.match(/detail/)
}
end
# ここがメインの部分
anemone.on_every_page do |page|
# クロールした結果をごにょごにょ
p page.doc.at('title').inner_html
end
end
```
# 結論
anemoneすごい。
Blogはこちら: [blog.tady.jp](http://blog.tady.jp)
### 最終更新日
- 2013-12-10
# 1行概要
Skypeの会話内容を準リアルタイム(遅延10秒)でChatworkの「マイチャット」に片方向転送するRubyのデーモンスクリプト。
ChatworkAPIを利用するように変更。
# 犯行動機
会社でskypeからchatworkへの移行をすすめるにあたって、その途中の「両方使ってる」微妙な段階の苦しみを取りぞぞくために。
# 覚書
- 12/10時点でmac限定
# コード
```ruby:sk2ch.rb
require 'fileutils'
require 'sequel'
require 'faraday'
# Skypeのアカウント
SKYPE_NAME = 'skype.id'
# ChatworkのAPIトークン
CHATWORK_API_TOKEN = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'
# Chatworkに投稿するグループID(マイチャットなど)
CHATWORK_ROOM_ID = '12345678' # charwork my chat
module LastId
DATA_PATH = File.join(File.expand_path(File.dirname(__FILE__)), 'last_id.txt')
# 前回のSkypeのMessageIDを取得、なければSkypeDBから最新のものを取得
def self.get
if File.exist?(DATA_PATH)
open(DATA_PATH).read
else
Skype::copy_db!
Skype::get_last_id
end
end
# ファイルにSkypeのMessageIDを保存
def self.set(last_id)
puts "last_id: #{last_id}"
open(DATA_PATH, 'w') { |f| f.write last_id.to_s }
end
end
module Skype
TMP_DB_PATH = '/tmp/skype-main.db'
# SkypeのDBをコピー
def self.copy_db!
FileUtils.copy("#{ENV["HOME"]}/Library/Application Support/Skype/#{SKYPE_NAME}/main.db", TMP_DB_PATH)
rescue => err
p err
retry
end
# Skypeの最後のMessageIDを取得
def self.get_last_id
connection = Sequel.connect("sqlite://#{TMP_DB_PATH}")
dataset = connection.fetch("SELECT id FROM Messages ORDER BY id DESC LIMIT 1")
dataset.first[:id]
end
# Skypeの最近の更新の差分を取得
def self.get_message
last_message_id = LastId::get
connection = Sequel.connect("sqlite://#{TMP_DB_PATH}")
dataset = connection.fetch("SELECT Messages.id, Messages.from_dispname, Conversations.displayname, Messages.body_xml FROM Messages LEFT JOIN Conversations ON Messages.convo_id = Conversations.id WHERE Messages.id > ?", last_message_id)
new_last_message_id = last_message_id
dataset.each do |r|
puts "[#{r[:from_dispname]}] #{r[:displayname]}\n\t#{r[:body_xml]}"
yield r
new_last_message_id = r[:id]
end
LastId::set(new_last_message_id)
end
end
module Chatwork
# ChatworkにPOST
def self.post(text)
conn = Faraday::Connection.new(url: 'https://api.chatwork.com') do |builder|
builder.use Faraday::Request::UrlEncoded
builder.use Faraday::Adapter::NetHttp
end
response = conn.post do |request|
request.url "/v1/rooms/#{CHATWORK_ROOM_ID}/messages"
request.headers = {
'X-ChatWorkToken' => CHATWORK_API_TOKEN
}
request.params[:body] = text
end
end
end
loop {
Skype::copy_db!
Skype::get_message do |message|
Chatwork::post("#{message[:displayname]} (#{message[:from_dispname]})\n#{message[:body_xml]}")
sleep(1)
end
sleep(1)
}
```
## 細かい内容
- SkypeのDB(sqlite)は排他制御で読み取りすら出来ないので、強引にコピーしSQLを実行して最新の情報を取得
## 参考
[30秒でChatwork APIを使ってマイチャットに投稿する方法](http://qiita.com/tady/items/ac6de448e228a2f631db)
# 1行概要
# 1行概要
例えば社内で自分のPCに開発サーバを立てたけど、IPではなくホスト名で他のメンバーにURLを教えたいときに使う方法
# 犯行動機
- 社内DNSの再設定がめんどくさい
- Google APIのOAuth2のredirect_urlがグローバルでないとエラーになるため、社内ローカルでの開発が面倒
# 想定読者
- Railsの開発がいくつか並行している
- ローカルにDNSが無い OR 設定する程ではない
- Google OAuth2の `invalid redirect url` エラーで詰まった
# 方法
## 1. xip.ioを使ったDNS解決
外部のパブリックDNSサービス [xip.io](http://xip.io) を使います。
![Screen Shot 2013-12-04 at 8.33.14 AM.png](https://qiita-image-store.s3.amazonaws.com/0/10272/20efc664-3921-1a34-de41-a89fec2fef55.png)
アカウント登録の必要はなく、自分のPC(開発機)のローカルIP(例: 192.168.1.123)の場合、
` some-project.192.168.1.123.xip.io `
をブラウザに入力するだけ。
すると、 `xip.io ==> 192.168.1.123` と名前解決されます。
## 2. nginxのNamed virtuel Host設定
xip.ioは名前解決しかしてくれないので、自分のPC(開発機)に複数のプロジェクトが走っているとポートを使い分ける必要があり、いろいろ面倒です。
そんな時は、nginx(Apacheでも可)のNamed virtuel Host機能を使います。
``` nginx.conf
server {
listen 80;
server_name some-project.*; # <= ここがミソ!
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://localhost:3000; #<= ポートをサービスごとに変える
break;
}
}
}
server {
listen 80;
server_name another-project.*; # <= ここがミソ!
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://localhost:3001; #<= ポートをサービスごとに変える
break;
}
}
}
```
## 3.アプリケーションの起動(Railsの場合)
あとは、Railsのプロジェクトディレクトリで、
```sh:/path/to/some-project
bundle exec rails s -p 3000
```
```sh:/path/to/another-project
bundle exec rails s -p 3001
```
と実行するだけ。
これで、
[some-project.192.168.1.123.xip.io](http://some-project.192.168.21.123.xip.io)
[another-project.192.168.1.123.xip.io](http://another-project.192.168.21.123.xip.io)
からアクセスできます。
以上
...@@ -3,7 +3,9 @@ namespace :batch do ...@@ -3,7 +3,9 @@ namespace :batch do
desc 'Tagに関連するPostのcounter_cacheの再生成' desc 'Tagに関連するPostのcounter_cacheの再生成'
task reset_counters: :environment do task reset_counters: :environment do
puts "\t[START] batch:reset_counters"
Tag.all.each{|t| Tag.reset_counters(t.id, :posts) } Tag.all.each{|t| Tag.reset_counters(t.id, :posts) }
puts "\t[FINISH] batch:reset_counters"
end end
end end
......
...@@ -6,7 +6,7 @@ Feature: アクセス制限 ...@@ -6,7 +6,7 @@ Feature: アクセス制限
Then response includes '<!--view:welcome/login-->' Then response includes '<!--view:welcome/login-->'
Scenario: 非ログイン --> postsページ Scenario: 非ログイン --> postsページ
When visit '/posts' When visit '/flow'
Then response code is 200 Then response code is 200
Then response includes '<!--view:welcome/login-->' Then response includes '<!--view:welcome/login-->'
......
...@@ -3,9 +3,18 @@ require 'spec_helper' ...@@ -3,9 +3,18 @@ require 'spec_helper'
describe ApisController do describe ApisController do
describe "GET 'markdown_preview'" do describe "GET 'markdown_preview'" do
it "returns http redirect" do
get 'markdown_preview'
expect(response).to redirect_to('/')
end
end
describe "GET 'markdown_preview'" do
login_user
it "returns http success" do it "returns http success" do
get 'markdown_preview' get 'markdown_preview'
response.should be_success expect(response).to be_success
end end
end end
......
...@@ -2,7 +2,7 @@ require 'spec_helper' ...@@ -2,7 +2,7 @@ require 'spec_helper'
describe ApplicationController do describe ApplicationController do
pending '#require_login' pending '#redirect_unless_signed_in'
pending '#after_sign_in_path_for' pending '#after_sign_in_path_for'
......
...@@ -2,11 +2,19 @@ require 'spec_helper' ...@@ -2,11 +2,19 @@ require 'spec_helper'
describe FlowController do describe FlowController do
describe "GET 'show'" do describe "GET 'show' without login" do
it "returns http redirect" do
get 'show'
expect(response).to redirect_to('/')
end
end
describe "GET 'show' with login" do
login_user login_user
it "returns http success" do it "returns http success" do
get 'show' get 'show'
response.should be_success expect(response).to be_success
end end
end end
......
...@@ -2,11 +2,19 @@ require 'spec_helper' ...@@ -2,11 +2,19 @@ require 'spec_helper'
describe SearchController do describe SearchController do
describe "GET 'show'" do describe "GET 'show' without login" do
it "returns http redirect" do
get 'show'
expect(response).to redirect_to('/')
end
end
describe "GET 'show' with login" do
login_user login_user
it "returns http success" do it "returns http success" do
get 'show' get 'show'
response.should be_success expect(response).to be_success
end end
end end
......
...@@ -2,11 +2,19 @@ require 'spec_helper' ...@@ -2,11 +2,19 @@ require 'spec_helper'
describe StockController do describe StockController do
describe "GET 'show'" do describe "GET 'show' without login" do
it "returns http redirect" do
get 'show'
expect(response).to redirect_to('/')
end
end
describe "GET 'show' with login" do
login_user login_user
it "returns http success" do it "returns http success" do
get 'show' get 'show'
response.should be_success expect(response).to be_success
end end
end end
......
...@@ -2,12 +2,22 @@ require 'spec_helper' ...@@ -2,12 +2,22 @@ require 'spec_helper'
describe TagsController do describe TagsController do
describe "GET 'show'" do let(:tag) { FactoryGirl.create(:tag_ruby) }
pending '...'
describe "GET 'show' without login" do
it "returns http redirect" do
get 'show', name: tag.name
expect(response).to redirect_to('/')
end
end end
describe "GET 'events'" do describe "GET 'show' with login" do
pending '...' login_user
it "returns http success" do
get 'show', name: tag.name
expect(response).to be_success
end
end end
end end
...@@ -15,18 +15,12 @@ describe 'Request via js', js: true do ...@@ -15,18 +15,12 @@ describe 'Request via js', js: true do
before :each do before :each do
login_as user, scope: :user login_as user, scope: :user
visit '/posts' visit '/flow'
end end
it 'show first post' do it 'show first post' do
page.save_screenshot(Rails.root.join('tmp', 'screenshots', "a-#{Time.now.strftime('%Y-%m-%d %H%M%S')}.png")) page.save_screenshot(Rails.root.join('tmp', 'screenshots', "a-#{Time.now.strftime('%Y-%m-%d %H%M%S')}.png"))
expect(page.find('.panel-title a').text).to include('java java') expect(page.find('.post-list:first-child h4').text).to include('java java')
end
it 'click post and show' do
find('.post-list:nth-child(3)').click
page.save_screenshot(Rails.root.join('tmp', 'screenshots', "b-#{Time.now.strftime('%Y-%m-%d %H%M%S')}.png"))
expect(page.find('.panel-title a').text).to include('ruby rspec')
end end
after :each do after :each do
......
...@@ -22,7 +22,7 @@ require 'capybara/poltergeist' ...@@ -22,7 +22,7 @@ require 'capybara/poltergeist'
def register_poltergeist(config) def register_poltergeist(config)
Capybara.register_driver :poltergeist do |app| Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, timeout: 60) Capybara::Poltergeist::Driver.new(app, timeout: 60, js_errors: false)
end end
# Capybara.run_server = true # Capybara.run_server = true
# Capybara.default_driver = :poltergeist # Capybara.default_driver = :poltergeist
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment