Kawaii Lab

プログラミングとかサービス開発とか

DBに依存しないRailsアプリケーションを作成した

現在こちらのPRで作成している

story0002 eat-backが徒歩圏内でランチができる店を知ることができる by KamabokoHouse · Pull Request #2 · KamabokoHouse/eat-back · GitHub

当初RailsではDBが必須だと考えていたのだが、調べたところによると必須ではないらしい。
恩恵はなくなるらしいが。

以上のことからRailsからDBの依存や、デフォルトで入っていたメーラーやジョブ関係も削除している

また悩んだのがビジネスロジックの配置場所だがappの直接配下におく事にした
実際のディレクトリ構成はこんな感じだ。

contolloer # リクエストを受けて適切なusecaseを選択する
- usecase # domainの処理を取りまとめて流すだけ
- domain # usecaseの処理内容を適切な責務に取り分けて格納している
- infrastructure # 外部との通信だけ行う

railsというかrubyは解決方法が曖昧でこれと言った解にたどり着くまでが長い...まるで魔術だ

テストは標準の機能ではなくRspecを採用する事にした。 UseCaseを使って書く以上、BDD形式のテストフレームワークがきっちりハマるのでこれ以上ない選択だと思っている。

Loggerについては以下のサイトがベストプラクティスだと思っているので、参考にしながらルール化していきたい。
Rails Logger and Rails Logging Best Practices

NextAction

infrastructureのユニットテストを書く

今日の進捗はDockerのDBイメージと連携で詰まった

現在Dockerの環境構築をしている

PG::ConnectionBad: FATAL: role username does not exist というエラーが出て接続できないので明日解消したいと思う
POSTGRES_USERに与えればRoleが作成されると思ったがそうではないのか...謎が深すぎる

docker-compose.yml

version: "3"

services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    ports:
      - "3000:3000"
    volumes:
      - ".:/app"
    depends_on:
      - db
    environment:
      - DATABASE_HOST=db
  db:
    image: postgres:10.1
    volumes:
      - datavol:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=username
volumes:
  datavol:

今日の進捗はRailsの自動CI/CDフローを整備した

以下の二つを達成した

  • devブランチにマージしたらdevサーバーにリリース
  • masterブランチにマージしたらstgサーバーにリリース

herokuだとpostgres DBしか使えなかったのでDBの変更もした。 記事によっては開発環境はSQLite3でherokuはpostgresが多かったのだが、環境構成が違うとトラブルになりがちで,余計な手間が増えるのでここはpostgresに統一した。

後学のためにRailsとCircleCI,Herokuの連携のために読んでおくべき記事を載せておく

Database Configuration Examples - CircleCI

Getting Started on Heroku with Rails 5.x | Heroku Dev Center

Circle CI 2.1 templates for deploying Ruby on Rails to Heroku with Ruby 2.6.0 and Node. This config deploys `develop` to staging and `master` to production. · GitHub

Next Action

Docker環境の整備

今日の進捗

やったこと

--apiオプションを使うためにRubyのVersionを2.6にあげた

fishだとrbenvのインストール方法が違う

fishでrbenvを導入する - Qiita

こちらの手順を実行後,rbenv initでインストール完了

githubリポジトリを作った

GitHub - KamabokoHouse/eat-back

CI/CDを回すまではmaster pushする

next action

CI/CDを導入して、PRベースでリポジトリにコミットできるようにする

story0002の設計をした

バックログ

サービス開発を始めるので要件定義をしてみた - there_you_moon’s diary

story0002

eat-backが徒歩圏内でランチができる店を知ることができる

AC

  • GET /restaurant から 半径800メートル圏内の店を取得できる
  • Dockerにより高速な開発環境が実現されている
  • CI/CDのデリバリーにより開発フローの秩序が保たれている

WA

条件

取得する店舗の条件は以下とする

  • 営業時間内
  • 営業終了まで1hの余裕がある

今後の拡張性を考えてバックエンドでは店を絞り込まない

アーキテクチャ

初期導入するアーキテクチャは以下の通り

DDDなどのデザインパターンは基本的に導入せずにRails Wayに乗っていく
SwaggerなどのAPI仕様書はエンドポイントが増えた場合に導入する

規約

外部と通信する場合は以下のタイミングで通信内容をログを出力する

  • リクエストの送信前
  • レスポンスの受信後

基本的にコメントは書かない。
しかし、制約などにより冗長な書き方をしなければいけない場合は理由を書く

ユニットテストインターフェイスに対して、ユースケースを把握するように実装する

API

Places API を使用する
Place Search  |  Places API  |  Google Developers

プラットフォーム

Herokuを使用する

  • サーバーは以下を用意する

ローカル開発環境

Docker化を行う
高速に開発できる Docker + Rails開発環境のテンプレートを作った - Qiita

CI/CD

  • CicleCIを使用する
  • 開発ルール
  • リリースルール
    • ビルド、デプロイを行う
    • デプロイはビルド時のキャッシュを使って行う
    • dev branchにpushでHeoroku devサーバーにリリース
    • master branchにpushでHeoroku stgサーバーにリリース

Rubyのクラスで使う変数について調べてみた

インスタンス変数

インスタンス変数はクラスのインスタンス毎に異なる値を持てる変数
基本的にはこちらを使うことになるだろう

@val

クラス変数

クラス変数はクラスのインスタンス全てで共有される変数
スコープが広いため通常の使用には適さないので、(そもそも別々に生成したオブジェクトが依存しあう関係はよろしくないのではないか)あまり使うタイミングはないと思われる。

@@val

クラス定数

クラス定数は一旦定義するとクラス内で変更ができなくなる変数
継承によるオーバーライドなどの条件に限り値を変更することができる。
特定の日時をもつパターンなど、個々のクラスで意識しなくていい値についてはこちらでいいだろう。 共通項目として開発者に意識させる効果も見込まれる。

VAL

実装するとしたらこんな感じだろうか
例を作るときにいいパターンが思いつかなくて困るな...

require 'date'

class Human
    TIME = Time.now.strftime("%H:%M")
    @@move = "can"

    def canAction
        p "only walk"
    end
end

class Jack < Human
    def initialize(swim)
        @swim = swim
    end

    def canAction
        p "I #@@move walk"
        p "I #@swim swim"
        p "It's time " + TIME
    end
end

class Candy < Human
    def initialize(swim)
        @swim = swim
    end

    def canAction
        p "I #@@move walk"
        p "I #@swim swim"
        p "It's time " + TIME
    end
end

jack = Jack.new("can")
candy = Candy.new("can't")

p "jack ..."
jack.canAction()

p "candy ..."
candy.canAction()
ruby Ruby/Class.rb

"jack ..."
"I can walk"
"I can swim"
"It's time 18:09"
"candy ..."
"I can walk"
"I can't swim"
"It's time 18:09"

Rubyを使っていて思うんだが、紛らわしい文法が多い気がする....
ルールを敷くのも大変だし、組織で開発する場合は苦労しそうだ

クックパッドのエンジニア採用イベントに行ってきた!

今回は以下のイベントに参加して参りました!

cookpad.connpass.com

オフレコの話もあるということなのでそこら辺はぼかして書いて行きたいと思います!

まず受付をすると、なんとクックパッドのロゴ入りトートバッグがもらえました!

f:id:there_you_moon:20190726192840j:plain
クックパッドのロゴが入ったトートバッグ
おしゃれで普段使いも捗りそうなデザインですねっ

受付をしたあとは飲み物を手に持ち、席へ...

その後は社員さんのトークを聞いて行きました。

投稿レシピが550万を超えているらしく、イギリス中心で海外展開しているらしいです。

Rubyがとても好きだけど、最近ではRuby以外の言語選定もしていて,GoとかJavaとかもいろいろ使ってるんですね。 ハードウェア開発もしてるのでアプリケーションエンジニア以外も応募してみる価値ありです。

既存のサービスが大きいので改修とか運用メインだと考えられがちですが、新規サービスの開発も積極的で知らないサービスが結構あってびっくりしました(e.g. : たべドリ)

ユーザーに対してネガティブな言動はほとんどないとか。 BtoCだと絶対あると思ってたのでここは意外でした。

SierなどWeb以外の業界の方も多くいて、プライベートで0=>1からサービスが作ったことがあるとかあると強いみたいです。 環境も月残業5h未満とかフルフレックスが稼働しているなど実際に聞いてみると感心してしまいますね。

トークを一通り聞いたあとは食事タイムです!

f:id:there_you_moon:20190726203747j:plain
豪華な料理が!
率直にいうとめちゃうまかった...鶏肉が柔らかくてパクパク食べれてしまうので食べ過ぎたかもです