OKR本を読んだ
はじめに
OKR(オーケーアール) シリコンバレー式で大胆な目標を達成する方法
- 作者: クリスティーナ・ウォドキー,及川卓也(解説),二木夢子
- 出版社/メーカー: 日経BP社
- 発売日: 2018/03/15
- メディア: 単行本
- この商品を含むブログ (1件) を見る
OKRの本を会社から支給されました。大事なことは原典を読んでいただくのが良いですが、気になったところを書いてみます。
スタートアップでもミッションを掲げるべき
どんなに夢のあるようなビジネスでも、マネタイズしなければ意味がないというのが自分の考えでした。しかし「お金がほしいなら、ウォール街のコンサルティング企業に入社するほうが遥かに安全だ。」という言葉をみてなるほどとおもいました。マネタイズは大事だけど、同じくらいミッションというか使命みたいなものが大事だと思います。
自信度の変化のトラック
今の会社でもOKRを取り入れていますが、自信度の変化をトラックしていません。はじめは50%でも自信度は刻々と変化していくため、OKRを振り返るためにも自信度の変化は重要であると考えました。
健康、健全性
これは、「利益に走りすぎて、エンゲージメントを失う」とか「締切を守るあまり、メンテナンス性の低いコードをリリースしてしまう」といった状況への抑止になると感じました。KRを達成さえすればそれでいいというような状況はなくなりそうです。
まとめ
OKRについて、まだまだ知らないことがあるなということと、これを遂行するにはメンバーのメンタリティも重要のように思いました。 あと、これとは別に「仕事はたのしいかね?」という本も読んでいてうーーーんという感じでした。
そもそもRailsでカスタム例外を定義すべき機会は少ない
はじめに
今仕事でRailsアプリケーションの運用をやっているのですが、いろいろなところで例外が定義されていて「これ必要なくね…」となんとなく思ったことが多々ありました。 しかし、effective rubyには「raiseにはただの文字列ではなくカスタム例外を渡そう」という章もあり、この違いはなんだろうと思いました。 なんでそう思ったのか整理して、今後自分のプログラミングに生かして行こうと思います。まとめると以下になります。
- カスタム例外を自分でraiseしてrescueするな。戻り値で判断しろ。
よく見るコード
Resourceモデル
class Resource Error = Class.new(StandardError) def write # 何かの処理 result = false # 何かの処理の結果falseだったと仮定 raise Error, '保存時にエラーが発生しました。' end end
Resourcesコントローラ
class ResourcesController < ApplicationController def create Resource.new.write redirect_to '/', flash: { notice: '作成されました' } rescue Resource::Error => e redirect_to '/', flash: { error: e.message } end end
よく見るコードがあまり良くない理由
- 処理の成功失敗を例外で返すようにすると、使いたいところで毎回例外処理を書かないといけないといけない。
- モデル側での処理が複雑になった場合に、大きい範囲をrescueする形になる。
- railsでは習慣的に、例外ではなく戻り値で判断する。
- 詳細はjnchitoさんの記事がわかりやすいです。
汎用性も可読性も低い。一般的でもないということですね…。
どうすればいいか
Resourceモデル
class Resource def write # 何かの処理 false # 何かの処理の結果falseだったと仮定 end end
Resourcesコントローラ
class ResourcesController < ApplicationController def create if Resource.new.write redirect_to '/', flash: { notice: '作成されました' } else redirect_to '/', flash: { error: '作成されませんでした' } end end end
カスタム例外は必要なくなりましたし、表示用のメッセージがモデルに縛られなくなりました。
結局カスタム例外は必要ないの?
必要ないとは言いませんが、単体のRailsアプリケーションを書いている場合、自分でraiseしようとしている例外はそもそもシステムエラーではなく業務エラー(日常的におこりうる)であることが多いように思いました。 もしそれがシステムエラーならば、rescueして握りつぶしては検知できないですし、そうなるとrescueしないんだからカスタム例外ではなくてもいいよねという話になると思い、最終的に独自例外いらないよねということになるんじゃないかなと思います。。。
gemなど不特定多数の人が使うものに関しては積極的に定義していくべきだと思います。gemから返ってくる例外がRuntimeErrorだとつらいですしね。
まとめ
やっぱりRailsでカスタム例外を定義すべき機会は少ないし、少なくとも自分はめったにやらないかなと思いました。
プロジェクトの立ち上げ時に入れてよかった/入れなくてもよかったgem
はじめに
ここ最近趣味でrailsアプリを複数人で開発しています。
自分以外Railsは初心者 で、rails newしてgemを入れてDB初期設計やってはじめのコントローラ(API)をつくるまで位を自分でやったのですが、その後入れてよかった/入れなくてもよかったと思うgemがあり、多少は他の人や未来の自分にも役立つだろうということで書き留めます。
入れてよかった
onkcop(rubocop)
コーディングスタイルについて揉めたり、議論したりすることがなかった。
自分が設定して満足できた。
bootstrap
本デザインが当たっていないサンプルの状態でも、まあまあいい感じに見せられる。素のHTMLを見ることによるテンションの落ちがない。
gimei
後述するseed-fuでのサンプルデータ作成に役立った。
ridgepole
migrationファイルの記法がほとんど使えるため学習コストが低かった。ちょこちょこスキーマを修正するのにいちいちmigrationを作らなくてよかった。(古いmigrationファイルを直せばいいというのもあるけど、ほんの少し罪悪感がある。)
seed-fu
サンプルデータをはじめに整備しておくことで、いろいろイメージが付きやすかったり、たたき台にできたり。
shrine
本番ではS3を使うのだが、developmentではローカルにファイルを置くとか実装を切り替えれたのが便利。初めてつかったけど carrierwave
をちゃんと使ったことがあればある程度は動かせた。
他の人を見ていると学習コストは高めだった。
capistrano-*
よくわからんままとりあえずgit pullでデプロイとかしなくてよかった。快適
入れなくても良かった
active_model_serializers
これを使いこなすためには きれいなAPI設計 がおそらく必要なのだけど、それがネックだった。 APIが汚いとserializerも汚くなる。 controllerでの手動よびだしとかするといまいち。 jbuilderや、素のhashを返すpure rubyのクラスを作って自前でas_jsonをしていくほうが、コスト低くある程度の規約ができてよかったかもしれない。
devise
自分が知っていたので立ち上がりは早かった。ただ、自分が入れてjwtなどの設定もしたので、自分が全部面倒見る感じになってしまった。 管理画面には積極的に使えばいいとおもう。
rspec
実際は「テスト各時間を取れなかった」という感じになる。作るものもよくわからないし、教える時間が満足に取れない状況ではどうしてもテストは後回しになってしまった。
まとめ
すべて学習コストとリターンのバランスかなという感じがしました!
Rails.cacheの落とし穴
はじめに
仕事で開発をしていた所、コードを動かしていてキャッシュされるべきところがキャッシュされないことがあったのでメモ。
結論
モデルをキャッシュする時、以下のようにしてもキャッシュされない。
@users = Rails.cache.fetch('user_all') do User.all end
なぜか
ActiveRecord
は評価を遅延させます。@users = User.all
としてもすぐにSQLが発行されることはなく@users.each
など発行するクエリが決まった段階でクエリ発行されるわけです。
結論に書いたケースだとUser::ActiveRecord_Relation
のインスタンスがキャッシュに入り、インスタンスが評価された段階でSQLが発行されるため、結果としてキャッシュを使っても毎回SQLが発行されてしまうわけです。
どうればいいか
上記の記事を参考にさせていただきました。
以下の用にto_a
を使ってクエリを即時発行すればOK。
@users = Rails.cache.fetch('user_all') do User.all.to_a end
webpackerのサンプルをparcelでつかったらautoloadが効かなかった
はじめに
parcelを使っていて動かすコードとしてwebpackerのreactのサンプルを使っていました。
その中で、parcelにはdefaultでautoloadの機能が備わっているのにloadされないという状態が起こりました。
ここでは原因とその対処法について書いていきます。
問題のコード
import React from 'react' import ReactDOM from 'react-dom' import PropTypes from 'prop-types' const Hello = props => ( <div>Hello {props.name}!</div> ) Hello.defaultProps = { name: 'David' } Hello.propTypes = { name: PropTypes.string } document.addEventListener('DOMContentLoaded', () => { ReactDOM.render( <Hello name="React" />, document.body.appendChild(document.createElement('div')), ) })
原因
以下のコードが問題でした。
document.addEventListener('DOMContentLoaded', () => { ReactDOM.render( <Hello name="React" />, document.body.appendChild(document.createElement('div')), ) })
autoloadはjsが再実行されるだけなので、addEventListener
で再度イベント登録しても、domがrenderされることはありません。
対処
まず、addEventListener
を使わずReactDOM.render
を即時実行するようにします。そうするとautoloadするたびにappendChild
されるので、getElementById
にして何個もdomが作られないようにします。html側にid要素をもつdivを一個作っておきました。
const mountNode = document.getElementById("app"); ReactDOM.render(<Hello name="React" />, mountNode);
jsのscriptタグがheadに書いてあったので、bodyの一番最後に変更してdivがある状態で読み込まれるようにもしました。
背景
Railsは基本scriptタグはheadに置くので、haedにおいても大丈夫なようにaddEventListener
を使った書き方になっているのだと思います。
まとめ
まだまだjsについては無知だなと感じました。
モチベーションを上げたい2〜猪子寿之の話に学ぶ〜
猪子寿之の話
https://ja.wikipedia.org/wiki/%E7%8C%AA%E5%AD%90%E5%AF%BF%E4%B9%8B
かなり前の話になるのだが、テレビで以下のような話をしていた。
- 仕事で海外に1人出張することが多く、いろいろとつらい
- 海外で自分の食べたいものを食べられないのがとくにつらい
- なので、どこでも食べられる目玉焼きを好きになることにした
- 本当に好きになってたまに目玉焼きを家でも作る
モチベーションアップに置き換える
- モチベーションの上がらない仕事を好きになる
- 何かモチベーションアップにつながるルーティンを持っておく
まとめ
結局のところ自己暗示の話なのだが、好きなものを変えるというのはなかなかぶっ飛んでいて面白いと思った。
「Presentational and Container Components」を読んだメモ
はじめに
さいきんちょこちょこReactやReduxをやっているのですが、いつも読んだドキュメントのことを忘れてしまうのでちょこちょこまとめて行こうと思います。
今回はReduxの作者でもある@dan_abramov氏の書いた、Presentational and Container Componentsです。
Presentational and Container Components
- コンポーネントをPresentationalとContainerに分けると、再利用がやりやすくなる。
presentational コンポーネントの特徴
- 見た目に関すること
- presentational/container コンポーネントのどちらも含む。
- DOM markupを含む。
- this.props.childrenによる封じ込めを許可する(?)
- アプリケーションの他の機能に依存がない
- データの扱いや操作は書かない
- propsを通じてデータやcallback関数を受け取る
- まれに自身のstateを含む(?)
- stateへのアクセスや、lifecycle hook、パフォーマンスの問題がない限り(?)はfunctionalにかく
- ex) Page, Sidebar, Story, UserInfo, List.
container コンポーネントの特徴
- どう動くかに関すること
- presentational/container コンポーネントのどちらも含む。
- ラップするためのdivを除いて、DOM markupを含まない
- dataや振る舞いを他のpresentational/containerコンポーネントに提供する。
- Flux actionを呼んでpresentationalコンポーネントにcallback関数として提供する(?)
- ステートフルで、データソースとして機能することが多い。
- 手で書かない。React Reduxのconnect()を使う。
- ex) UserPage, FollowersSidebar, StoryContainer, FollowedUserList.
このアプローチの利点
- アプリケーションとUIをよく理解できる
- 再利用性が上がる
- デザインだけの微調整ができる
- layout componentsだけを外出することができる。(?)
どちらのコンポーネントもemit DOM(?)を含まないこと
presentationalコンポーネントだけでアプリケーションを作ろうとするとpropsを渡す煩雑さに気づく。(?) propsを渡して歩くよりcontainerを使う方が良い場合がある。(?)
2つのコンポーネントの差はtechnical(?)なものではなく目的である。
宗教的に2つのコンポーネントを書き分けようとしないこと。 presentationかcontainerかわからなければ、あえて決めなくても良い。