GitHubGistで.vimrcを管理する
Cloud9でRails+React環境構築(3.Material-UIを動かしてみる)
はじめに
前回の続き sprink.hatenablog.com
引き続きこちらの記事を参考にさせて頂きました。 codezine.jp
手順
Yarnパッケージの追加
package.json(rails root直下)に以下を追加
(省略) "webpack-merge": "^4.1.0", "material-ui": "^0.18.0", "react-tap-event-plugin": "^2.0.1" }, (省略)
以下のコマンドを流す。
$ bin/yarn install
エラーが出る。
Yarn executable was not detected in the system. Download Yarn at https://yarnpkg.com/en/docs/install
あれ?最初の手順で入れたはず、、yarnのバージョンを確認してみる。
$ yarn -v bash: yarn: command not found
なさそう。
$ npm i -g yarn /home/ubuntu/.nvm/versions/node/v6.11.2/bin/yarn -> /home/ubuntu/.nvm/versions/node/v6.11.2/lib/node_modules/yarn/bin/yarn.js /home/ubuntu/.nvm/versions/node/v6.11.2/bin/yarnpkg -> /home/ubuntu/.nvm/versions/node/v6.11.2/lib/node_modules/yarn/bin/yarn.js /home/ubuntu/.nvm/versions/node/v6.11.2/lib └── yarn@1.3.2
入った。 念のためバージョンを確認。
$ yarn -v 1.3.2
気を取り直してもう一回実行する。
$ bin/yarn install success Saved lockfile. Done in 22.78s.
成功した。
ビューファイルを修正
app/views/pages/index.html.erb
<h1>Rails5.1サンプルアプリケーション</h1> <p>ReactベースのMaterial-UI(カード)を使う</p>
カードコンポーネントを呼び出すReactのコードを記述
まずjsxファイルを作る。
$ touch app/javascript/packs/expandable_example.jsx
以下を実装する。
app/javascript/packs/expandable_example.jsx
import React from 'react' import ReactDOM from 'react-dom' import PropTypes from 'prop-types' import {Card, CardActions, CardHeader, CardText} from 'material-ui/Card' import FlatButton from 'material-ui/FlatButton' import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme' import getMuiTheme from 'material-ui/styles/getMuiTheme' import injectTapEventPlugin from 'react-tap-event-plugin' injectTapEventPlugin() class CardExampleExpandable extends React.Component { constructor(props) { super(props) } getChildContext() { return { muiTheme: getMuiTheme(baseTheme) } } render() { return ( // カードコンポーネントのDOM <Card> // ヘッダー <CardHeader title="Rails 5.1サンプルアプリ開発" subtitle="Rails 5.1を体感する為のサンプルアプリケーションを開発する。" actAsExpander={true} showExpandableButton={true} /> <CardActions> <FlatButton label="完了" /> <FlatButton label="中止" /> </CardActions> <CardText expandable={true}> ・Rails 5.1より採用されたyarn,webpackを用いる<br/> ・Reactを採用しReactベースのMaterial-UIを入れてみる </CardText> </Card> ) } } CardExampleExpandable.childContextTypes = { muiTheme: PropTypes.object.isRequired } document.addEventListener('DOMContentLoaded', () => { ReactDOM.render( <CardExampleExpandable />, document.body.appendChild(document.createElement('div')), ) })
起動確認
$ bin/rails s -b $IP -p $PORT
コンパルでエラーが出る。
[Webpacker] Compiling… [Webpacker] Compilation failed: (省略) ERROR in ./node_modules/react-tap-event-plugin/src/TapEventPlugin.js Module not found: Error: Can't resolve 'react-dom/lib/EventConstants' in '/home/ubuntu/workspace/react_sample/node_modules/react-tap-event-plugin/src' @ ./node_modules/react-tap-event-plugin/src/TapEventPlugin.js 22:21-60 @ ./node_modules/react-tap-event-plugin/src/injectTapEventPlugin.js @ ./app/javascript/packs/expandable_example.jsx
画面は表示された。と思ったら、古い画面。
呼び出すjsxの変更
app/javascript/packs/application.jsを変えないといけない。
//require('./hello_react.jsx') require('./expandable_example.jsx')
コンパルエラーを解決
ググったら以下のissuesを発見
Not compatible with react 16 · Issue #109 · zilverline/react-tap-event-plugin · GitHub
react-tap-event-pluginを以下のバージョンに変更
"react-tap-event-plugin": "^3.0.0"
完成
Cloud9でRails+React環境構築(2.Reactを動かしてみる)
はじめに
前回の続き sprink.hatenablog.com
引き続きこちらの記事を参考にさせて頂きました。 codezine.jp
手順
application.html.erbのjavascript_include_tagを変更
app/views/layouts/application.html.erb
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
を
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
へ変更
hello_react.jsxをインクルード
app/javascript/packs/application.js
require('./hello_react.jsx')
bin/webpack-dev-serverを実行
$ bin/webpack-dev-server
エラーが出る(途中でRubyのバージョンを変えたせいかも)
rubygems.rb:270:in `find_spec_for_exe': can't find gem bundler(前後省略)
Bundler再インストール(念のため「bundle install」も)
$ gem install bundler $ bundle install
もう一度、bin/webpack-dev-serverを実行
$ bin/webpack-dev-server
webpack: Compiled successfully.
と表示されたらwebpackのコンパイルが成功(いつまで経ってもコンソールが止まったままなのでCtrl+Cで停止した)
起動確認
$ bin/rails s -b $IP -p $PORT
Hello, React!が表示される
Cloud9でRails+React環境構築(1.下準備)
はじめに
下記を参考に構築してみた。
手順
Cloud9でworkspaceを作成
Dashborad画面で「Create a new workspace」をクリック
workspace情報を設定
- 「Workspace name」を入力
- 「Rails Tutorial」を選択
- 「Create workspace」をクリック
Rubyインストール
$ rvm install 2.4.1
Bundlerインストール
$ gem install bundler
nodeインストール
$ nvm install v7.10.0
npmのアップデート
$ npm update -g npm
yarnインストール
npm i -g yarn
Rails5.1環境構築
フォルダ作成&移動
$ mkdir react_sample $ cd react_sample
Bundler
$ bundler init
Gemfileのrailsのコメントアウトを外す
# frozen_string_literal: true source "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } gem "rails"
bundle installを実行
パスをvendor/bundle配下に、gemインストールを並行して行う数を4で実行
$ bundle install --path vendor/bundle --jobs 4
rails new
実行中にGemfileの更新を求められるのでYで更新
$ bundle exec rails new . --webpack=react
Overwrite /home/ubuntu/workspace/react_sample/Gemfile? (enter "h" for help) [Ynaqdh] Y
gitignoreに下記を追加
/vendor/bundle
ここらでいったんgithubへ
Githubにリモートリポジトリを登録
TOP画面で「New repository」をクリック
「Repository name」を入力し、「Create repository」をクリック
Githubへプッシュ
$ git add . $ git commit -m "Initial commit" $ git remote add origin git@github.com:(アカウント名)/react_sample.git $ git push origin master
サンプル画面作成
コントローラ生成
$ bin/rails g controller pages index
ルートを定義 config/routes.rb
root to: 'pages#index'
いったん起動確認
$ bin/rails s -b $IP -p $PORT
Cloud9メニューから「Preview」〜「Preview Running Application」を選択 さらにページ上の「Open the App」をクリック(初回のみ)
ページが表示される
【Rails】Railsのログの読み方
はじめに
Railsのログについて、実装の過程で出てきたログをもとに読み方をまとめてみた。
ログの格納場所
Railsは実行環境ごとに異なるログファイルを出力される。
ログの格納場所は、デフォルトでRails.root/log/となっており、ログのファイル名は、アプリケーションが実行されるときの環境が使用される。
<具体例>
development環境 → development.log
test環境 → test.log
production環境 → production.oog
ログの内容
正常処理時
基本となるGET、POST、PATCH、DELETE別に解析してみた。
一覧表示【GET】
Started GET "/users" for 127.0.0.1 at 2017-06-06 00:03:08 +0900 Processing by UsersController#index as HTML Rendering users/index.html.erb within layouts/application [1m[36mUser Load (0.2ms)[0m [1m[34mSELECT "users".* FROM "users"[0m Rendered users/index.html.erb within layouts/application (9.2ms) Completed 200 OK in 1069ms (Views: 1050.6ms | ActiveRecord: 1.7ms)
1行目
Started [メソッド] [アクセス先] for [アクセス元IP] at [時間]
→ いつ、どこから、どのメソッドでどんなアクセスがされたか
2行目
Processing by [コントローラ名#メソッド名] as HTML
→ 処理が行われたコントローラとメソッド名と取得した形式
3行目
Rendering [レンダリングされたビューファイル名] within layouts/application
→ レンダリングの内容
4行目
[1m[36mUser Load (0.2ms)[0m [1m[34mSELECT “users”.* FROM “users”[0m
→ [1m[36とか謎の文字列がある。これは、
ANSI shell color codes というものらしく、以下のstackoverflowに情報があった。 stackoverflow.com
上記を取り除くと
mUser Load (0.2ms) SELECT “users”.* FROM “users”
となり、mUserが読み込まれ、ログにあるようなSQLが流れたことを示す。0.2msはかかった時間。
5行目
Rendered users/index.html.erb within layouts/application (9.2ms)
→ layouts/application内でusers/index.html.erbがレンダリングされた。
6行目
Completed 200 OK in 1069ms (Views: 1050.6ms | ActiveRecord: 1.7ms)
→ HTTPステータスコードと処理にかかった時間が表示される。
(ちなみに「200 OK」は、リクエスト成功時に返すレスポンスコード)
データの作成【POST】
Started POST "/users" for 127.0.0.1 at 2017-06-06 06:33:30 +0900 Processing by UsersController#create as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"YyULtXbbHrvd0PtDCocKrWIHSBGfbYJ/xD8V0TyWlWnRiEvFAP0Vu7Aaf/3V9t2FijWXRyLWKiMfbWxIPmjI6A==", "user"=>{"name"=>"aba", "text"=>"a"}, "commit"=>"Create User"} [1m[35m (0.1ms)[0m [1m[36mbegin transaction[0m [1m[35mSQL (1.0ms)[0m [1m[32mINSERT INTO "users" ("name", "text", "created_at", "updated_at") VALUES (?, ?, ?, ?)[0m [["name", "aba"], ["text", "a"], ["created_at", "2017-06-05 21:33:30.094146"], ["updated_at", "2017-06-05 21:33:30.094146"]] [1m[35m (0.9ms)[0m [1m[36mcommit transaction[0m Redirected to http://0.0.0.0:3000/users/2 Completed 302 Found in 7ms (ActiveRecord: 2.1ms)
(重複したログは省略)
3行目
Parameters: [パラメータの内容]
パラメータの内容。ちなみにパスワードなどはログに書き込まれたくないので、
config/initializers/filter_parameter_logging.rb
Rails.application.config.filter_parameters += [:password]
で、フィルタをかける項目の定義が行える。 なお、フィルタの項目は、ログでは[FILTERED]に置き換えられる。
4行目
begin transaction
→ トランザクションの開始
5行目
実行されたSQL
6行目
commit transaction
→ トランザクションのコミット
7行目
Redirected to [リダイレクト先のURL]
→ 記載のURLにリダイレクトされた
データの更新【PATCH】
Started PATCH "/users/2" for 127.0.0.1 at 2017-06-06 06:33:39 +0900 Processing by UsersController#update as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"c6CWUAYKwBihYJh+GCoOZv1XMgALdnzrA6mC9nqVa1bz1gajw3KZ696HEUg28xh00SIriwfZDIktPesXZymLyA==", "user"=>{"name"=>"abad", "text"=>"ad"}, "commit"=>"Update User", "id"=>"2"} [1m[36mUser Load (0.2ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?[0m [["id", 2], ["LIMIT", 1]] [1m[35m (0.1ms)[0m [1m[36mbegin transaction[0m [1m[35mSQL (0.6ms)[0m [1m[33mUPDATE "users" SET "name" = ?, "text" = ?, "updated_at" = ? WHERE "users"."id" = ?[0m [["name", "abad"], ["text", "ad"], ["updated_at", "2017-06-05 21:33:39.981554"], ["id", 2]] [1m[35m (0.9ms)[0m [1m[36mcommit transaction[0m Redirected to http://0.0.0.0:3000/users/2 Completed 302 Found in 8ms (ActiveRecord: 1.8ms)
目新しいログは無し
データの削除【DELETE】
Started DELETE "/users/1" for 127.0.0.1 at 2017-06-06 06:33:26 +0900 Processing by UsersController#destroy as HTML Parameters: {"authenticity_token"=>"vMMe9vhpLIjJ+6/krjCuflIVGEJ15gxwEAbQ0FBZiJNchaAIqXiX52Ntps6ZM94rVyg6NLNXxkTBP7ec4qFMRg==", "id"=>"1"} [1m[36mUser Load (0.3ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]] [1m[35m (0.1ms)[0m [1m[36mbegin transaction[0m [1m[35mSQL (0.6ms)[0m [1m[31mDELETE FROM "users" WHERE "users"."id" = ?[0m [["id", 1]] [1m[35m (0.9ms)[0m [1m[36mcommit transaction[0m Redirected to http://0.0.0.0:3000/users Completed 302 Found in 8ms (ActiveRecord: 2.0ms)
こちらも目新しいログは無し
エラー発生時
Started GET "/users/new" for 127.0.0.1 at 2017-06-06 06:07:05 +0900 Processing by UsersController#new as HTML Rendering users/new.html.erb within layouts/application Rendered users/_form.html.haml (6.0ms) Rendered users/new.html.erb within layouts/application (10.3ms) Completed 500 Internal Server Error in 44ms (ActiveRecord: 1.8ms) ActionView::Template::Error (Illegal nesting: nesting within plain text is illegal.): 6: 7: %ul 8: user.errors.full_messages.each do |message| 9: %li = message 10: end 11: 12: %div{ class: "field" }
この時は、ビューでエラーを出してしまった。6行目で「500 Internal Server Error」の記述の後、 具体的な内容がログに出ている。
おまけ
ログファイルをクリアするコマンド
rake log:clear
おわりに
ほんの一例ではあるが、まずはログの場所と大まかな内容の理解ができた。
【メモ】お客様との打合せ時のポイント(時間管理編)
概要
打合せ時の進行ポイントをまとめた。今回は「時間」に関するポイント。
準備、打合せ、打合せ後のポイント
打合せ準備、打合せ後などについては以前の記事参照 sprink.hatenablog.com
心構え
打合せの時間=「打合せ時間」×「参加人数」
これはよく言われることではあるが、参加人数が多ければ多いほど、トータルの会議時間は増えていく。 1時間で8人出席でも、1日分の時間が消費される。これが1時間伸びて2時間になろうものなら、2日分...そう考えると安易に会議を開催すべきでは無いし、予定時間を過ぎないように(できれば目的を達成しつつ早く終わるように)すべきである。
最大の効果を生む
通常、打合せは予め決められた時間で行われる。前半の議題で時間を使いすぎると、後半の議題に対して十分な時間が確保できず、安易な結論・決定がされがちである。十分な効果を出すために適切に進行する必要がある。
時間管理方法
準備段階でしておくこと
配布するレジュメの題目ごとに時間を書いておく。 また、配布しない場合でも準備段階で時間をメモしておく。当然、時間の妥当性も事前に確認しておく。 時間がシビアな打合せの場合は、レジュメに時間を記載したものを参加者で共有し、打合せ開始時に説明しておくと進めやすい。
予定通り進んでいるか
進行しながら題目ごとの時間を確認する(このペースで時間内で進行できそうかどうか判断していく)。 ひとつの題目で時間がオーバーすると、その後も時間が厳しくなるので題目などの区切りで時間を守るように進行する。 いちいち時計やレジュメを見ると、相手が気になってしまう場合もあるのでレジュメの時間は頭にいれておく(相手に気にしてもらうためにやる場合もあるが)。時間の経過具合もできれば時計を見ずに判断できるとなお良い。
予定通り進んでいない場合
よほどの準備不足でなければ、話がそれることが原因。 それた話を戻す必要がある。
別の課題に発展
→「なるほど、◯◯◯◯◯の課題ですね。検討事項に追加しておきます。今日はあまり時間も無いので、いったん元の課題に話を戻します。」などいったん区切り、かつ検討事項一覧や議事録に課題としてきちんと残して話を戻す。会議に関係の無い話
→雑談的な話はお客様とのコミュニケーションの一環として重要ではある。ただ、時間がない場合は話を戻す必要がある。「では、いったん話を戻しますね。」などと、角が立たないように話を戻す。想定よりも議論が長引く
→想定よりも時間がかかる議題だった場合、課題が大まか過ぎる可能性がある。「細分化→個々に解決」、または「総論的に方向性を出し、各論は別途解決」するなどの対応を行う。単に細分化して解決しそうであれば前者、細分化しても各論同士で、折り合いが付きにくく全体の方向性の取り決めが必要な場合は後者の方法が良い。想定よりも早く終わり過ぎる
→題目のゴールに到達していれば問題が無いが、議論が十分だったか注意する。
予定通り進みやすくする準備
打合せ中の対処だけでなく、なるべくそうならないようにするテクニックとしては、参加者に時間を意識させることである。 具体的には、「題目ごとの時間の提示」だけでなく「なぜ時間通りの進行が必要か」の理由を伝えることがある。
【メモ】お客様との打合せの進め方
概要
システム開発・導入等において、お客様と打合せする際のポイントをまとめた。
準備段階
出席者
出席者、出席者の位置づけ(権限、キーマンかどうか)を確認する。 お客様だけでなく、自分の会社側の出席者についても、役割等打合せで何を期待するかは 事前にすり合わせしておく。役割が無いのであれば、出る必要はない。
必要なもの
会議のレジュメがあると進行しやすいし、後述の会議のイメージもつきやすい。 資料として出す必要がなくても自分用には作るべき。
目的
「打合せすること」が目的になりがちであるが、今一度目的を確認して 「今から準備しようしている打合せの準備は目的を達成できるもの」であるか確認する。
ゴール
目的を達成するために、何がどうなれば良いのか。具体的なゴールを定義しておく。 また、何かを決定する場合はお客様の「誰」に決定権があるのか事前に想定しておく。
例)XXX画面の画面レイアウトを決定する。
XXXの担当者を決定する。
ゴールはレジュメなどに記載し、打合せ時に出席者と認識を合わせると良い。 また、ゴールが「運用フローを決定する」というような大きな場合は、細分化したものを リスト化し、ゴールを小口化すると良い。こうすると全部終われば達成であるし、残っているものは 残課題として今後対処すれば良いものとして明示的になる。
イメージ
準備した資料、出席者をイメージし、頭の中でざっとシミュレーションを行う。 そこで、懸案になりそうなものがあれば事前に回答の準備をしておく。 ここでどれだけイメージし、事前準備できるかが実際の打合せ時のパフォーマンスに大きく影響する。 打合せのパフォーマンスが上がれば、そのプロジェクトに大きくプラスに働く。
打合せ時
時間管理
決まった時間に始める。当たり前のことではあるが、打合せの場所が初めて訪問した場所だと部屋がわからない。 また、お客様とうまく調整できておらず誰を尋ねれば良いかわからないなど、色々とトラブルが起きやすい。 リスクを想定しておき、早めに現地入りするべき。
決まった時間に終わる。打合せは伸びがちであるが、お客様と約束した枠内の時間で終わるように進行すべき。 話が脱線してもすぐ戻したり、検討が長くなりそうであれば、持ち帰りにしてもらう等の工夫が必要。
資料
事前に席に配布し、数に不足がないか確認しておく。
システム画面
できるだけ実際の画面で説明して進める。口頭であれこれしても伝わりにくい。 ”百聞は一見に如かず”である。
最後に決定事項、懸案事項の確認
打合せは、何かを決定する場所なので決定事項は打合せ中に都度確認していくが、 打合せの最後にもおさらいとして全ての決定事項を確認し、認識に誤りがないか漏れが無い確認しておく。 懸案事項についても同様。
次回日時・内容確認/調整
後日でも良いが、可能であればその場に関係者がいるので次回日時も調整しておくと効率的。 次回の内容は、持ち帰りの懸案事項の結果が影響する場合もあるが、こちらもできる限りその場で調整しておいた方が良い。
(トラブルシューティング1)決定したいが、決定権がある人が欠席
「次回に出席してもらおう → また出席しない」というまずいケースになりがち (そもそも出席すべき打合せにでていないので、次回も欠席するケースが多い) 打合せ後にお客様内で確認してもらい、その結果を後日連絡してもらうか次回打合せ時に結果をもらう。
(トラブルシューティング2)決定したいが、そもそも決定する人が決まっていない
誰が決めるか決定してもらう。
→そもそもプロジェクト開始の時点で決まっていた方が良い(お客様含めた体制図)。
当初想定してないものであれば、後日体制図に加筆し関係者で認識を合わせておく。
打合せ後
議事録の作成
- 定型の議事録フォーマットがあればそれで作成し、参加者に送付する。 打合せ時に配布した資料も添付すると良い。 形式張ったものでなくても良いのなら、メール文章内で書いたメモをそのまま送付でも良い。
- 目的は「自分、その他出席者用の備忘録」だけでなく、出席できなかった人への情報共有、 また、言った言わないのトラブルを避けるため。
次回打合せに向けた課題事項への対応
決定事項、懸案事項には速やかに対応する。特に懸案事項について、早期対応の必要が高いものは すぐにやり、問題が小さいうちに対処する。
最後に
打合せをどう進めるのが効率的かどうかは、そのプロジェクトの性質に大きく影響する。 ある程度自分の中でフレームワークを作りつつ、そのプロジェクトに合ったテーラリングして効率化したい。