毎週技術的なブログを書く為に実践していること

今年のお正月からなんとなく毎週ブログを更新するというのを初めて10回を超えたので自分なりに振り返ってみようと思う。

ネタ探しについて

まだ10回なんだけど、業務内容にも恵まれてるのかもしれんがぶっちゃけあまり困ってないです。 ネタはたくさんある方だと思っているけど、裏を取るために動かしたり色々調べたりするのがとにかく面倒...*1

過去にやって見たことを引っ張り出してる。

別に技術ブログには「今やっていること」「将来やりたいこと」を書くというレギュレーションはない。 三年前に書き散らしたコードをブラッシュアップしてブログに出す、のでもいいと思う。

自分の記事だと、 これは投稿した時点よりも2〜3ヶ月前にライブラリの素体は出来上がっていたので、 ブログに投稿する記念にHerokuにデプロイとDockerイメージとしてPushしたくらいで、他に特別なことはしていない。

webuilder240.hatenablog.com

自作ライブラリについてをブログに書く

自分で便利で作ってみたライブラリとアウトプットを両立するためにライブラリを書くだけじゃなくて、 日本語でもいいから、説明をブログに残しておくというのはいい方法かもしれない。 自分はまだ経験ないけど、誰かに見つけてもらって使ってもらう...なんてこともあるかもしれないし。*2

webuilder240.hatenablog.com

アップデートした場合は、アップデートについて書くのもいいかもしれない。 些細なアップデートでも立派なアウトプットである。

webuilder240.hatenablog.com

本当に些細・ニッチなものでもとにかく投稿してる

忘れてはならないのは、「バズ」のために記事を書いているわけではないということだ。 自分の書いたブログはひたすらはてブ0がならんでいるし、承認欲求を満たすことは出来ていない。 個人的にムカつくのでリンクは貼らないけど、 Qiitaにあるような「フロントエンドの用語・技術だけを雑に集めた雑なリンク集」がブックマークを集めるのが昨今の現状である。

とにかく、他人の評価は気にせずに、自分で正しいと思ったことをとにかく続けることに専念しよう。 承認欲求に関しては、まぁブックマークきたらうれしいねーくらいにしておいたほうが良いかもしれない。 webuilder240.hatenablog.com

最初の一歩を大事にする為に...

かける時に書けるだけ書く、でも欲張らない

とにかく馬力があるときにまとめて7割位まで書けるときは書いてしまったほうが良いと思っている。 書きたいことだけをブログに下書きでつらつら並べておいて、 その後はその項目について調べたりで終わるくらいにするのが一番いいと思ってる。

誘惑に負けない方法

明らかにモンハンをやってる時期は手を抜いていた。 手を抜くことはわかっていたので、軽めの記事で「とにかく繋ごう」と言う気持ちで、 あっさり目のものを書いたり、先に書いた通り、事前に8割方書けるときに貯金しておくという方法で乗り切った。

誘惑に負けない方法は個人的には無いと思っており、 「好きなことを好きなときにやる」のが一番なので、その時は「しっかりゲームで遊ぶ」ことを最優先にしてました。 またプログラミングばかりやるフェーズはやってくると思っているので...

今の所モンハンに200時間くらい時間を溶かしてるけど、無理なく続いてる。*3

今はとりあえず続けるだけを目標にしているだけなので、半年か1年続けたらやめようと思ってる。

やめたあとは定期投稿でなくていいので、アウトプットの質を高める方をやってみようかなと思っている。

*1:やると楽しいんだけどね

*2:今回はブログを続けるコツで、余り期待しない方がいい。

*3:この投稿も投稿をつなぐための施策だったりする。

FirestoreをRubyのgoogle-api-clientから叩く

そもそもRubyからFirestoreを叩きたい理由

  • FirestoreはフロントエンドからWriteできるけど、実装の複雑さを避けるためにフロントエンドからはWriteしないで、 チャットのAPI経由でFirestoreに対してWriteを行う機構が必要だったため。*1 *2

方法

  1. とにかくgoogle-api-clientをインストールする
  2. サービスアカウントの認証JSONKeyを取得する
  3. サービスアカウントの権限に追加すればOK

ここまでの方法は調べればいくらでもあるので、他の記事等を参考にして進めて欲しい。 ちょっと画面がややこしいので、この部分を含めても解説しても良かった気がするが時間がないので、また追記します。 以降は実際にコードとしてどう書けばいいか、というのを雑に並べておきます。

require 'google/apis/firestore_v1beta1'
SCOPE = ['https://www.googleapis.com/auth/datastore', 'https://www.googleapis.com/auth/cloud-platform']
PROJECT_ROOT_PATH = "projects/hoge-project/databases/(default)"
client = Google::Apis::FirestoreV1beta1::FirestoreService.new
client.authorization = Google::Auth::ServiceAccountCredentials.make_creds(
  json_key_io: File.open("#{Rails.root}/config/hogehoge.json"),
  scope: SCOPE
)

message = Message.first

# firestoreにドキュメントを追加
def push_firestore(message)
  client.create_project_database_document_document("#{PROJECT_ROOT_PATH}/documents", 'messages', message_doc(message))
end

# firestoreの指定したドキュメントを削除
def destroy_firestore(firestore_message_id)
  client.delete_project_database_document("#{PROJECT_ROOT_PATH}/documents/#{firestore_message_id}")
end

# firestoreのフィールド設定
def message_doc(message)
  doc = Google::Apis::FirestoreV1beta1::Document.new()
  doc.fields = {
     "id": {
        integer_value: message.id
     },
     "content": {
        string_value: message.content
     },
     "created_at": {
        timestamp_value: message.created_at.rfc3339
     },
     "updated_at": {
       timestamp_value: message.updated_at.rfc3339
     }
  }
  doc
end

これでとりあえずgoogle-api-client経由でドキュメントの作成と削除ができる状態になった。 ほかにもたくさんFirestoreのAPIがあるみたいなので、それはまた今後眺めてみることにする。

感想

  • 特にexampleのコードとかなかったし、とにかくわかりづらい印象だった。Gemの中身をちゃんと読みまないと絶対にわからん。
  • 各項目に対して型を設定するのがいちいち面倒、ちゃんと使う分には何某かのうっすいラッパーくらいあっていいかも。

参考リンク

*1:あとは私がサーバサイドエンジニアだったのでというのも理由ひとつ

*2:参考: https://speakerdeck.com/sota1235/realtime-messaging-with-firebase-number-phpcon2017

自作のサービスのsinatraのバージョンをアップしました。

ogp_parse_apiというサービスを適当に運用・Dockerイメージを提供しているのですが、 こちらで利用しているSinatra脆弱性の修正を含むバージョンアップがあったのでその対応をしました。

github.com

ogp_parse_apiは単純にOGP情報をスクレイピングしてJSONで表示するだけの単純なサービスです。 詳しいことはこちらの記事をご参照ください。

webuilder240.hatenablog.com

経緯

こんな感じでGithubから通知が到着していた。

どうやらSinataraの脆弱性の修正が含んだバージョンアップがあったらしく、 そのためSinatraをアップデートしてくれーと通知欄に来ていたので対応しました。

f:id:oh240:20180224231002p:plain

f:id:oh240:20180224225922p:plain

やったこと

至極簡単で、 bundle updatebundle exec rspec

をやってテストが通ったので、コミットして、GitHubにPush。 さらにHerokuにDeployして作業終了。 簡単なアプリケーションだけど、テストを書いているので安心感をもってリリースできたのでテスト書いててよかった。

Gemを初回インストールした時にメッセージを表示する post_install_message

自作のGemで初回インストール時にメッセージを表示したいケースがある場合に重宝する。 まだ自分でちゃんと運用しているわけではないけど、 社内Gemの場合はREADMEやMigrationしてねーみたいなメッセージを付けてあげるのが親切・便利かと思う。

spec.post_install_message = File.read('UPGRADING.md')

Specification Reference - RubyGems Guides

PaparClipでCSVをS3にアップロードした時にContent-Typeが"text/plain"になってしまう問題

概要

PaperClipで、Railsで生成したCSVファイルをS3にアップロードするときに、Content-Typeが"text/plain"でアップロードされてしまうので、 S3にアップロードしたときに.txtファイルになってしまう問題がある。

とりあえずの解決方法

とりあえずS3にアップロードするタイミングでヘッダーにContent-Typeに"text/csv"を設定すればとりあえずOK。

今回利用したかったケースはシステム内部で生成したCSVをS3にアップロードする要件なので。 特にバリデーション周りが雑なんだけどまぁこんな感じで。

  class Document < ActiveRecord::Base

    has_attached_file :document,
      storage: :s3,
      s3_credentials: "#{Rails.root}/config/private_s3.yml",
      s3_permissions: :private,
      path: "example.com/:id/:filename"
      
    validates_attachment :document, less_than: 512.megabytes
    do_not_validate_attachment_file_type :document

  end
  class DocumentCsv < Document
    has_attached_file :document,
      storage: :s3,
      s3_credentials: "#{Rails.root}/config/private_s3.yml",
      s3_permissions: :private,
      path: "example.com/:id/:filename",
      s3_headers: {"Content-Type" => "text/csv"}
  end