Note

3年後の自分のために書いています

ActiveRecord で create_xx, build_xx 系のメソッドが作られるのは has_one した時だけ

表題の通りですが、 has_many した時も create_xxs 的なメソッドが自動生成されると勘違いしていたのでメモ。

ActiveRecord::Associations::ClassMethods

class Project < ActiveRecord::Base
  has_one :project_manager
  has_many :milestones
end

Project#create_project_manager(attributes={}) はいけるけど、 Project#create_milestones(attributes={}) はいけないという話。

やっぱり Rails ガイドよりも Ruby on Rails API の方が正確かつ詳細な情報があって良いですな。

高階関数とカリー化をそろそろ理解したい with JavaScript

あとでサンプルコード追加するかも。

早く Haskell やれやって話なんですけどね。

この記事のシリーズがだいぶ分かりやすかった。

tech.recruit-mp.co.jp

高階関数

関数を『引数』もしくは『返り値』として扱う関数のこと。

カリー化

期待される数より少ない引数で関数を呼び出した場合に、残りの引数を取るためにその呼び出された関数が別の関数を返すような関数。

JavaScript のスプレッド構文とレスト構文がややこしいので Ruby の配列展開と splat パラメータで理解する

細かい仕様の違いはあるかもしれないが、大体以下の感じで理解している。

スプレッド構文

Array に関しては Ruby でいう配列の展開(*)とほぼ同じかな。

スプレッド構文を使うと、関数呼び出しでは 0 個以上の引数として、Array リテラルでは 0 個以上の要素として、Object リテラルでは 0 個以上の key-value のペアとして、Array や String などの iterable オブジェクトをその場で展開します。

function sum(x, y, z) {
  return x + y + z;
}

const numbers = [1, 2, 3];

console.log(sum(...numbers));
// expected output: 6

console.log(sum.apply(null, numbers));
// expected output: 6

関数呼び出しとかと一緒に使わないで単独で ...numbers とかってやると syntax error になる。(これは Ruby も同じ)

Object に関してはまだ proposal っぽいけど、JS の方はそのまま Object のまま展開されるのに対して、 Ruby のハッシュ展開は以下のように配列に変換されるのでちょっと仕様が違いそう。

$ irb

> hash = { x: 1, y: 2, z: 3 }
=> {:x=>1, :y=>2, :z=>3}
> a, b, c = *hash
=> [[:x, 1], [:y, 2], [:z, 3]]
> a
=> [:x, 1]
> b
=> [:y, 2]
> c
=> [:z, 3]

レスト構文(分割代入)

レスト構文はスプレッド構文と全く同じ見た目をしていますが、Array や Object の分割代入に使われます。こちらはスプレッド構文とは逆の働きといえます: スプレッド構文が要素を展開するのに対して、レスト構文は複数の要素を集約して 1 つのオブジェクトにします。

Array

Ruby で可変長引数を扱うための splat パラメータ(*)とほぼ同じかな。

function sum(...theArgs) {
  return theArgs.reduce((previous, current) => {
    return previous + current;
  });
}

console.log(sum(1, 2, 3));
// expected output: 6

console.log(sum(1, 2, 3, 4));
// expected output: 10

Object

Ruby のダブル splat パラメータ(**)の object でやり取りする版かな。(Ruby のはキーワード引数リストをハッシュとして受け取る)

今はまだ Proposal のようだ。

Rest/Spread Properties for ECMAScript 提案 (ステージ 3) は、分割代入に rest 構文を追加します。残余プロパティは、分割パターンによってすでに取り出されていない、残りの列挙可能なプロパティのキーを収集します。

let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
a; // 10 
b; // 20 
rest; // { c: 30, d: 40 }

参考

スプレッド構文 - JavaScript | MDN

Rest parameters - JavaScript | MDN

分割代入 - JavaScript | MDN

GitHub - tc39/proposal-object-rest-spread: Rest/Spread Properties for ECMAScript

Rubyのパラメータと引数の対応付けを理解する(前編)

クラス/メソッドの定義 (Ruby 2.6.0)

メソッド呼び出し(super・ブロック付き・yield) (Ruby 2.6.0)

個人開発で使えそうな API まとめ

完全に自分用のメモ。 軽い調査結果も残しておく。

求人検索

Google Job Search API (Cloud Talent Solution)

GCP アカウント必要、アカウント作ると12ヶ月3万円無料期間始まるので開発直前に始めた方がいい

Cloud Talent Solution documentation  |  Job Search documentation  |  Google Cloud

Linkedin API

新しいMSのドキュメントには求人検索系 API 載ってないかも?

Recommended Jobs | LinkedIn Developer Network

Indeed Job Search API

パブリッシャー登録 必要、会社名と Web サイトの URL がいる

Job Search API

勉強会・交流会

Meetup

認証は OAuth2、プロキシサーバ必要

Extend your community | Meetup

Doorkeeper

CORS 対応しており、プロフィールから アプリケーション登録 すればプロキシサーバ無しでクライアントから利用可能

Doorkeeper API | Doorkeeper

connpass

Same-origin policy に引っかかるので、プロキシサーバ必要

APIリファレンス - connpass

VSCode x TypeScript x ESLint で自動整形する

2019/12/23 Update

この記事の内容は不要になったっぽい。

Revisions of "VSCodeでESLint+@typescript-eslint+Prettierを導入する(v2.0.0修正版)" - Qiita

以下、元記事。

JS のプロジェクトを TS に変更したら ESLint の整形が効かなくなったのでメモ。

VSCodesettings.json に以下を追加すればOK。

  "eslint.validate": [
    "javascript",
    "javascriptreact",
    {"language": "typescript", "autoFix": true },
    {"language": "typescriptreact", "autoFix": true }
  ]

"javascript", "javascriptreact" も書かないと js への整形が効かなくなる。

参考

GitHub - microsoft/vscode-eslint: VSCode extension to integrate eslint into VSCode

Autofix lightbulb not shown in TypeScript · Issue #609 · microsoft/vscode-eslint · GitHub

Haskell を亀のようなスピードで学び始めている私のための Stack による環境構築メモ

React x Flow or TypeScript の開発をやるにあたり、関数型言語と型システムの知識がないことがボトルネックになってきたと感じるので、ずっと積んでいた『すごいH本』を亀のようなスピードで進めている。

2012年に出版されたこの本には Haskell Platform による環境構築方法が載っているのだけれど現在は Stackを使った方法が推奨されているらしい。

だいたい以下のドキュメントに書いてある通りなのだけれど、一応 REPL を動かすところまでメモしておく。

Home - The Haskell Tool Stack

$ curl -sSL https://get.haskellstack.org/ | sh
$ stack --version
Version 2.1.3, ...
$ where stack
/usr/local/bin/stack

# REPL (ghci) 立ち上げ
$ stack exec ghci

# show type
Prelude> :t putStrLn
putStrLn :: String -> IO ()
# Hello, World!
Prelude> putStrLn "Hello, World!"
Hello, World!
# exit
Prelude> :quit

2021/08 追記

参考

Download Haskell Platform

GitHub - commercialhaskell/stack: The Haskell Tool Stack

https://qiita.com/waddlaw/items/49874f4cf9b680e4b015

GraphQL のエラーハンドリングについていろいろ調べた

前提

GraphQL のレスポンスのフォーマットに関するベストプラクティスとして、レスポンスの HTTP ステータスコードは 200 で統一、レスポンスの errors キーにエラーの詳細な情報を持たせる というのがある(公式な仕様ではないが、Apollo Client も graphql-ruby もこれに沿っている)

最初にまとめ

GraphQL のエラーハンドリングにはトップレベルの errors キーにエラー内容を持たせる方法と、 data キーの中にエラー内容を持たせる方法とある。

公式の仕様書には前者の トップレベルの errors キーにエラー内容を持たせる方法のみが載っている

後者は公式の仕様には無いが graphql-ruby に実装されている機能 なので使える。

しかしエラーの type を定義できないと、エラーの詳細が動的に変わりうるということなので、エラーハンドリングをクライアント側で UI として表現する場合は data キーの中に含めた方が堅牢なアプリケーションになる。(トップレベルの errors キーに含める場合も type 定義できれば良いのだけれど)

説明

レスポンスの形式でいうと以下のような感じ。

トップレベルの errors キーにエラー内容を持たせる

{
  "errors": [
    {
      "message": "Can't continue with this query",
      "locations": [
        {
          "line": 2,
          "column": 10
        }
      ],
      "path": ["user", "login"]
    }
  ],
  "data": {
  // 同じレスポンスに data を含めることもできる
  // ...
  }
}

data キーの中にエラー内容を持たせる

{
  "data": {
    "createPost": {
      "post": null,
      "errors": [
        { "message": "Title can't be blank", "path": ["attributes", "title"] },
        { "message": "Body can't be blank", "path": ["attributes", "body"] }
      ]
    }
  }
}

その他

GraphQLにおけるエラーハンドリングの仕方 - ZOZO Technologies TECH BLOG がめっちゃ参考になった。

ちなみに graphql-ruby では 最近の PR でルートの Schema クラスに rescue_from を定義できるようになり、セーフティネット的なエラーハンドリングを実現できるようになった

これ調べてる間に graphql-ruby のドキュメントのリンク切れを見つけて投げた PR、 無事マージされた。