レバテックキャリアさんに、前職在籍時に書いた記事を取り上げていただいた
レバテックキャリアさんの記事はこちらです。 また、取り上げていただいた記事そのものはこちらです。
2017年2月21日、ということで、ちょうど1年と5ヶ月前の記事になりますが、取り上げていただけるなんて、ありがたい話ですね。
Web制作会社と自社サービス会社の違いについて、少しでも知る手がかりになれば幸いです。
さて、偶然なことに、まさに今も「転職して4ヶ月くらい経った」タイミングだったりします。
今回は「自社サービス開発」どうしの転職ではあるのですが、「入社当時 社員5名未満の超スタートアップ」から「上場後で社員300名超のミドルベンチャー」の転職です(ただし某ブラックホールではありません、フロア違いです 笑)。
エンジニアの規模としては、3人から11人(インターン・アルバイト含む)に変わりました。
ですので、ついでに、今回の転職で変わったことを書いてみようと思います。
以前やっていたこと
上記の記事から抜粋。
- CSS芸人
- CoffeeScript(からES6にリプレース)
- Ruby on Rails実装(複雑なところをのぞく)
- UI改善ディレクション
現在やっていること
- CSSレビュアー
- Vue.js実装・レビュアー
- Ruby on Rails実装(初期実装ほぼ全体)
- インフラのお勉強
変わったこと
技術に集中できるようになった
現在の会社では「ディレクター」や「デザイナー」がいらっしゃるので、サービスの方針とか、デザインの方針とかを考えるのはお任せする感じになりました。もちろん、発言権がないわけではなく、意見があれば都度相談することもあります。
ですので以前よりは、技術のことを考える時間が増えました。あとは、コードレビューでレビュアーになることもグッと増えました。
プロジェクト内での役割について考えるようになった
以前はほとんど1人でフロントエンドもサーバーサイドも実装し、軽く上長に相談する程度で開発を進めていたのですが、上記に伴い、いろんな役割の人がいるので、たとえば
「これはディレクターにも相談するべきなんだっけ」
とか、
「ここはデザイナーに調整してもらった方がいいんだっけ」
とか、考えるようになりました。
なので、良くも悪くも「テキトーに、いい感じにやっとけばいいや」っていうふうに進められなくなったな、と思います。
専門家に相談できる強さがある
これも上記に関連するのですが、現在は、フロントエンドも、サーバーサイドも、インフラも、それぞれ専門家がいるので、相談相手に困らなくなりました。
なので、現在自分が関わっているプロジェクトには、ディレクターやデザイナー含め、たくさんの専門家がメンバーをサポートしてくださっています。ありがたい話です。
まとめ
やはり人数がいる強さってすごいな、に尽きます。
ただ、自分は現在ゼネラリストとしてやっているところがあるので、これ以上大きい組織になった時に、専門家でない自分が果たして役に立てるのかな...?なんて迷ったりすることもあります。
インフラお勉強中なので、ひと通り慣れてきたら、自分の道を決めるタイミングになるのかもしれません。
とはいえそれでも優秀なエンジニアさんは、自分の専門外の技術もある程度キャッチアップしていたりするので、そういうところを見習いながらやっていきたいな、と思っています。
PercelでVueを動かしてみた
職場で話題になったので動かしてみました。すごく簡単でした。
調べてみると、流行った頃の日本語の記事がいろいろ記事が出てきたんですが、Percel側もあれから開発が進んで、ますます簡単になっていたようです。
こんな感じなので、日本語の記事を参考にするより、公式ドキュメントを見た方がはるかに簡単でしたw
ということで、早速やってみます。
まずは、プロジェクトルートのディレクトリを作ります。
今後はその中で作業していきます。
公式ドキュメントに書いてある通り、まずは Vue
と parcel-bundler
をインストールします。
$ npm install --save vue $ npm install --save-dev parcel-bundler
そして、 package.json
に script
を追加します。
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "parcel index.html" },
初期設定はこれだけ。
あとは、プロジェクトルートにビルドしたいファイルを追加していきます。
index.html
<!doctype html> <html lang="ja"> <head> <meta charset="utf-8"> <title>parcel-vue</title> </head> <body> <div id="app"></div> <script src="app.js"></script> </body> </html>
app.js
import Vue from 'vue/dist/vue.esm.js'; import Hello from './vue/hello.vue' const app = new Vue(Hello); app.$mount('#app');
vue/hello.vue
<template> <p> {{ message }} </p> </template> <script> module.exports = { data: function() { return { message: 'Hello, Percel-Vue!!', } } } </script> <style scoped> p { font-size: 64px; text-align: center; color: #3eaf7c; } </style>
ビルドしたいファイルを追加したら、先ほど package.json
に追加した script
で動かしてみましょう。
$ npm start index.html
Server running at http://localhost:1234
の文字が出たら、 http://localhost:1234
から確認できます。
Webpackのconfigには自分も悩まされてきたので、Percelの今後に期待です。
RailsのModelで定義するlengthのvalidationについて、activemodelのコードを見てみる
今日はさっぱりめ。
Railsでmodelを書くときって、こんな感じに書くと思うんですが、
class User < ApplicationRecord validates :name, presence: true, length: { maximum: 30 } validates :email, presence: true end
昨日お仕事で length
のカスタムバリデーションを書きたくなり、このデフォルトの length
の実装ってどうなってるんだろう? と思ったので、調べてみました。
該当箇所はこちら。
7/7 10時現在のソースは以下。
# frozen_string_literal: true module ActiveModel module Validations class LengthValidator < EachValidator # :nodoc: MESSAGES = { is: :wrong_length, minimum: :too_short, maximum: :too_long }.freeze CHECKS = { is: :==, minimum: :>=, maximum: :<= }.freeze RESERVED_OPTIONS = [:minimum, :maximum, :within, :is, :too_short, :too_long] def initialize(options) if range = (options.delete(:in) || options.delete(:within)) raise ArgumentError, ":in and :within must be a Range" unless range.is_a?(Range) options[:minimum], options[:maximum] = range.min, range.max end if options[:allow_blank] == false && options[:minimum].nil? && options[:is].nil? options[:minimum] = 1 end super end def check_validity! keys = CHECKS.keys & options.keys if keys.empty? raise ArgumentError, "Range unspecified. Specify the :in, :within, :maximum, :minimum, or :is option." end keys.each do |key| value = options[key] unless (value.is_a?(Integer) && value >= 0) || value == Float::INFINITY || value.is_a?(Symbol) || value.is_a?(Proc) raise ArgumentError, ":#{key} must be a nonnegative Integer, Infinity, Symbol, or Proc" end end end def validate_each(record, attribute, value) value_length = value.respond_to?(:length) ? value.length : value.to_s.length errors_options = options.except(*RESERVED_OPTIONS) CHECKS.each do |key, validity_check| next unless check_value = options[key] if !value.nil? || skip_nil_check?(key) case check_value when Proc check_value = check_value.call(record) when Symbol check_value = record.send(check_value) end next if value_length.send(validity_check, check_value) end errors_options[:count] = check_value default_message = options[MESSAGES[key]] errors_options[:message] ||= default_message if default_message record.errors.add(attribute, MESSAGES[key], errors_options) end end private def skip_nil_check?(key) key == :maximum && options[:allow_nil].nil? && options[:allow_blank].nil? end end module HelperMethods # Validates that the specified attributes match the length restrictions # supplied. Only one constraint option can be used at a time apart from # +:minimum+ and +:maximum+ that can be combined together: # # class Person < ActiveRecord::Base # validates_length_of :first_name, maximum: 30 # validates_length_of :last_name, maximum: 30, message: "less than 30 if you don't mind" # validates_length_of :fax, in: 7..32, allow_nil: true # validates_length_of :phone, in: 7..32, allow_blank: true # validates_length_of :user_name, within: 6..20, too_long: 'pick a shorter name', too_short: 'pick a longer name' # validates_length_of :zip_code, minimum: 5, too_short: 'please enter at least 5 characters' # validates_length_of :smurf_leader, is: 4, message: "papa is spelled with 4 characters... don't play me." # validates_length_of :words_in_essay, minimum: 100, too_short: 'Your essay must be at least 100 words.' # # private # # def words_in_essay # essay.scan(/\w+/) # end # end # # Constraint options: # # * <tt>:minimum</tt> - The minimum size of the attribute. # * <tt>:maximum</tt> - The maximum size of the attribute. Allows +nil+ by # default if not used with +:minimum+. # * <tt>:is</tt> - The exact size of the attribute. # * <tt>:within</tt> - A range specifying the minimum and maximum size of # the attribute. # * <tt>:in</tt> - A synonym (or alias) for <tt>:within</tt>. # # Other options: # # * <tt>:allow_nil</tt> - Attribute may be +nil+; skip validation. # * <tt>:allow_blank</tt> - Attribute may be blank; skip validation. # * <tt>:too_long</tt> - The error message if the attribute goes over the # maximum (default is: "is too long (maximum is %{count} characters)"). # * <tt>:too_short</tt> - The error message if the attribute goes under the # minimum (default is: "is too short (minimum is %{count} characters)"). # * <tt>:wrong_length</tt> - The error message if using the <tt>:is</tt> # method and the attribute is the wrong size (default is: "is the wrong # length (should be %{count} characters)"). # * <tt>:message</tt> - The error message to use for a <tt>:minimum</tt>, # <tt>:maximum</tt>, or <tt>:is</tt> violation. An alias of the appropriate # <tt>too_long</tt>/<tt>too_short</tt>/<tt>wrong_length</tt> message. # # There is also a list of default options supported by every validator: # +:if+, +:unless+, +:on+ and +:strict+. # See <tt>ActiveModel::Validations#validates</tt> for more information def validates_length_of(*attr_names) validates_with LengthValidator, _merge_attributes(attr_names) end alias_method :validates_size_of, :validates_length_of end end end
パッと見「ハテ?」という気持ちにもなりますが(笑)、自分たちが普段Modelで定義しているのは、最初の方に書いてある以下の部分ですね。
MESSAGES = { is: :wrong_length, minimum: :too_short, maximum: :too_long }.freeze CHECKS = { is: :==, minimum: :>=, maximum: :<= }.freeze
この MESSAGES
と CHECKS
が使われているところから読んでみたらわかりやすかったです。
あとは、 validate_each
メソッドの中にある、以下の部分でデータの length
を出しているんだな、とか。
value_length = value.respond_to?(:length) ? value.length : value.to_s.length
そしてこの後に続いて、値のチェックをしたり、エラーを出したりしてるんだなー、とか。
CHECKS.each do |key, validity_check| next unless check_value = options[key] if !value.nil? || skip_nil_check?(key) case check_value when Proc check_value = check_value.call(record) when Symbol check_value = record.send(check_value) end next if value_length.send(validity_check, check_value) end errors_options[:count] = check_value default_message = options[MESSAGES[key]] errors_options[:message] ||= default_message if default_message record.errors.add(attribute, MESSAGES[key], errors_options) end
RailsにおけるModelのvalidationは日々当たり前に使っている部分ですが、より身近なものに感じることができました。
Pythonの素人がDjangoアプリケーションをlocalhostで立ち上げるまで
これまで全くPythonは触ったことなかったのですが、機械学習ブームだったり、Ruby25のイベントでMatzさんがPythonの話をしてたりしたので、すこし興味がありました。
RubyやPHP、JavaScriptと同じスクリプト言語だし、ちょっと見てみたいな、と思ったところで、こんな本が出ていました。
「ふりがなプログラミング」シリーズは話題になっていたので個人的に欲しいなと思っていたのですが、せっかくなら未履修の言語をやってみたいと思ったので、JavaScriptではなくPythonの方を買ってみました。
内容はプログラミング未経験者向けなので、変数や関数、リストやループなどの基本的なしくみが、Pythonの文法も含めて、しっかり解説されていました。
このあたり、自分は学生時代にJavaの入門書で独学したのですが、ここまでやさしくは説明されていなかったので、結構大変だった記憶があります。いい時代になったなあ。
Pythonの文法は、SlimやSass(not Scss)、CoffeeScriptなどのように基本閉じなくてよくて、インデントやスペースで制御されている感じなのが楽でいいなーと思いました。
あとは前述の通りスクリプト言語なので、普段RubyとJavaScriptをやっている自分でも、ハードルに感じた内容は特になかったように思います。解説もやさしかったし。
Djangoを使ってみる
さて、本題に戻ります。Djangoですね。
今のところ自分は機械学習に対してハードルを感じているので、RailsやLaravelみたいなアプリケーションなら触れそうだと思ったのが、Djangoを触ってみようと思ったきっかけです。
ただ、Ruby on RailsやVue CLI、Nuxt.jsみたいな爆速initに慣れてしまった身には、Djangoの公式ドキュメントが少しハードル高めに感じたので(笑)、最終的にはDjango Girls Tutorialを参考に進めていくのが良かったです。
並行して、日本語では以下の記事を参考にさせていただきました。
pythonのインストール
自分は別のプロジェクトの関係で direnv
と pyenv
を使っていました。
なので、まずは pyenv
を使って3系のPythonをインストールしました。
$ pyenv install 3.6.1
次に、プロジェクト用のディレクトリを作成します。
$ mkdir django-tutorial $ cd django-tutorial
direnv
を使うために、以下の記述のある .envrc
を作成します。
pyenv local 3.6.1
あとは、以下のコマンドを使えば、このプロジェクトの中だけでpython3.6.1を動かすことができるようになります。
$ direnv allow
Python仮想環境のためのvirtualenv導入
ここでは以下の記事を参考にさせていただきました。
上記の通りに進めていきます。
$ sudo easy_install virtualenv # すでにプロジェクト用のディレクトリ内にいるため、カレントディレクトリで実行 $ virtualenv --no-site-packages . $ source bin/activate
Djangoプロジェクトの作成
Django Girls Tutorialにしたがって、Djangoをインストールします。
Django自体は、もっと新しいバージョンが出ているようですね。
$ pip install django~=1.11.0
Djangoのプロジェクトを作成します。
$ django-admin.py startproject mysite .
migrateします。
$ cd mysite
$ python manage.py migrate
ここまで進んだら、以下のコマンドでローカルサーバーを立ち上げることができます。
http://127.0.0.1:8000/
から確認してみましょう。
$ python manage.py runserver
ローカル環境を立ち上げるのはここまでですが、Django Girls Tutorialではmodelやviewの作成など、実際にPythonを用いて定義していく部分も含まれますので、Pythonを文法をサッと学んだ身としては、ここからが醍醐味だなあ、という感じです。
Electronのwebviewでブラウザ版Slackを見ようと挑戦して詰んだ話
公式アプリがあるのに、どうして車輪の再発明なことをわざわざやろうと思ったのか?
それは、これがやりたかったから。
もちろん、会社Slackなどの重要事項が流れてくるTeamではやりませんが、
基本ROMってるTeamで、SNS疲れみたいな気持ちになりたくないなーというのがありまして。
あと、Electronが未履修なので一回触っておきたいな、と思いました。
そういうことで、まずはElectronを動かしてみます。
上記の公式サイトでQuick Startをやってみます。
# Clone the Quick Start repository $ git clone https://github.com/electron/electron-quick-start # Go into the repository $ cd electron-quick-start # Install the dependencies and run $ npm install && npm start
こんな感じで動きました。超簡単!
続いて、webviewを試してみましょう。
以下は公式ドキュメントです。
こちらにある以下の部分を、ルート直下にある index.html
にコピーしてみます。
<webview id="foo" src="https://www.github.com/" style="display:inline-flex; width:640px; height:480px"></webview>
不要なところは削除して、こんな感じ。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Hello World!</title> </head> <body> <webview id="foo" src="https://www.github.com/" style="display:inline-flex; width:640px; height:480px"></webview> <script> // You can also require other files to run in this process require('./renderer.js') </script> </body> </html>
再度 npm start
で動かしてみます。
おお、GitHubのページが見られましたね!
webviewの幅や高さが微妙なので、CSSを追加します。
html { width: 100%; height: 100%; } body { margin: 0; padding: 0 height: 100%; }
CSSを読み込むため、 index.html
に <link rel="stylesheet" href="style.css">
を追加します。
そして、webviewの src
属性を、 https://www.github.com/
から https://slack.com/signin
に変更してあげます。
これで再度 npm start
してみましょう。
おお、なんかそれっぽくなってきました。
試しにログインしてみます。けれど、サインインした瞬間にフリーズしますね...😭
ひとまず表題の件については今回はここまで。
フリーズの原因がわかったら続きをやっていきたいと思います。笑
Vuepressをサッとビルドして、Netlifyでサッとデプロイしてみた
すごく今更感があるのですが、先日Vuepressを立ち上げてみたので、雑にその様子を書いてみます。
最初はVuepressで、こっそり掃き溜めブログでも作ろうかなって思ったんだけど、Kibunlogというアプリが掃き溜めにとてもよかったので、Vuepressでの公開は特にしていません。
Vuepressのビルドについては公式サイトの通り。
# install yarn global add vuepress # OR npm install -g vuepress # create a markdown file echo '# Hello VuePress' > README.md # start writing vuepress dev # build to static files vuepress build
これでサッとビルドができます。
ディレクトリ構成や設定ファイルについては以下が参考にできます。
.md
ファイルが記事なので、ファイルを増やすと記事も増やせます。
デプロイについても公式ドキュメントがあります。
自分は今回Netlifyを使いました。
まず、Netlifyにデプロイするために、Vuepressのプロジェクトで git init
して、GitHubのリポジトリにPushします。
また、今回自分はNetlifyを使うのが初めてだったので、GutHubのアカウントと連携して、Netlifyのアカウントを作成しました。
Netlifyでアカウントを作成してログインをしたら、右上に「new site from Git」ボタンがあるのでそれをクリックします。
デプロイしたいVuepressのリポジトリを選択して、デプロイ設定に進みます。
ヘッダーメニューの「Settings」に進んで、左サイドバーの「Build & deploy」の「Edit settings」からデプロイの設定ができます。
Vuepress公式ドキュメントのこちらを参考に、Netlifyを設定します。
これで、GitHubのリポジトリにpushをすると自動デプロイされるようになっていると思います。
pushしてデプロイがうまくいったかどうかは、Netlifyのヘッダーメニューの「Overview」から確認できます。
以上、サッとビルドしてサッとデプロイしたときの雑なメモでした。
Vuepressについての日本語記事でとてもいいなーと思ったのは、有料記事にはなってしまいますがCodeGridの@nakajmgさんの記事です。
サッと作るだけではなく、Vuepressをきちんと作り込みたいなって思った時に参考になると思います!
ダイエットアプリ、睡眠アプリ、英語アプリの話
ゆるゆるダイエットをはじめました
きっかけはこれです。
朝食バイキングで同部屋の子たちの1.5倍の量を、同じスピードで食べ終わっていたので流石に自分で引いた。。
— meru.yml (@c5meru) May 28, 2018
社員旅行によって自分が食べ過ぎていることに気づけたの良かった
— meru.yml (@c5meru) May 28, 2018
昨日今日と食事の量を少し減らしているけれど、頭がさっぱりしている感じがする
あと、温泉入る前に体重計に乗ったら増えすぎててビックリしました。
ということで、こちらを導入しました。
やってることとしては以下です。
- 大江戸線六本木駅で階段を使う
- AppleWatchとアプリを連携して運動量を記録
- 体重を毎日記録
- 食事を毎回記録
- 朝はカロリーメイトハーフサイズ
- 昼はサラダと焼き魚
- 夜は自炊(ライザップご飯のレシピ本を参考)
こんな感じ。
まだはじめたばかりだけど、2キロくらい減っています。
まあ、まだ誤差の範囲内なので、油断せずに続けます。
AppleWatchで睡眠を測りはじめました
ここしばらく寝つき / 寝起きがあまり良くない気がしているので、睡眠を測りはじめました。
睡眠の質は悪くなさそうだと安心したら、すこし寝つき / 寝起きが改善された気がします。
上手く眠れてないと思い込んでて悪循環だったのかもしれません。
英語の勉強を習慣づけています
それから、英語の勉強もサボり気味だったので、リマインダー通知できちんと行動管理するようにしました。
英語の勉強は以下のアプリでやっています。
ある程度慣れてきたら英作文もできるようなものを試して、そのあと英会話をやってみようと思っています。
発音の練習
聞き取り・ディクテーション
英単語
リマインダー
一気にいろいろはじめすぎて、全部破綻しそうな予感がめっちゃしているけれど、うまくいくと楽しいし、ひとつくらいできなくても落ち込みません。
最近、なにかの数字を見るのが好きだな、と思うのです。 家計簿とか、カロリーとか。
内定を辞退してTwitterで転職活動をしました
先駆者であるひよこ大佐(@hiyoko_taisa)さまに敬意と感謝をこめて。
こんばんは。めるです。表題の通りです。
年末の時点で次に行く(はずだった)会社が決まりまして、1月末で退職をしていました。
しかし、最終出社1日を残したあたりで状況が一転、内定を辞退して転職活動を再開することになりました。
内定を辞退した理由については、直接聞いてもらうか、時期でお察しください。。
有給を使いきっていたのもあり、もともとバッファで2週間だけ無職になることにしていましたが、それにしても早く職に就かねばならない、ということでTwitterで求職してみることにしました。
諸事情により、ゆる募。
— める@3/1から働きます! (@c5meru) 2018年1月29日
Rails歴1年2ヶ月、PHP歴1年、フロントエンド歴3年程度のエンジニアを雇ってもいいよ、というところ。
その他の経歴等につきましては、TwitterプロフィールのURLをご参照ください。
Twitterで求職しようと思ったのは
- 一度内定が出ていて、個人的に満足のいく年収だったので、それベースで年収交渉できそうだった
- もう退職することになっているので、現職に内緒で転職活動をやる必要がなかった
という理由があります。これがなかったらやってないです。
思い切ってツイートしてみたところ、リプライ、DM、Eメール、Facebookなどで、30社ほどの企業さまよりお声がけいただきました。
お声がけいただいた皆さま、本当にありがとうございました。
この出っ張ってるところが求職した日です pic.twitter.com/UhixcKzSUM
— める@3/1から働きます! (@c5meru) 2018年2月11日
まずはテキストベースで
- 技術スタック
- 組織体制
- 想定されるポジション
などをヒアリングさせていただいて、実際にお会いさせていただいた企業さまは10社くらいになります。
もともと「バッファの2週間」だったので、沖縄行ったり、親知らず抜いたり、デブサミに行ったりしていたため、全部で3週間くらいかかりましたが、そういうのがなければ2週間でいけたんじゃないかな、と思っています。
自分はコードレビューの記事の件もあり、とても残念なことに、技術力よりもSNS力や知名度のほうが先行してしまっている傾向があるため(早くなんとかしないと...)、普通では難しいと思われる企業さまからも、Twitterのおかげでお声がけいただけたりしました。
あとは、互いのニーズがある程度一致したうえで初回面談できるのがよかったです。
改めて決まった転職先については落ち着いたらまた書きますが、実は、年末に一度内定が出たくらいの時期に、旦那(@polidog)経由でお声がけいただいていた企業さまなので、Twitterきっかけではないところで決まってしまったという。。
でも、Twitter経由でお会いした企業さまも、全部本当に素敵な企業さまだったので、今までの転職活動の中で一番有意義なものになったと思います!!ほんとに!!
改めて、今回の転職活動でお声がけくださった皆さま、リツイートしてくださった皆さま、そして旦那さまも(笑)、本当に本当にありがとうございました。
Vue.jsでインクリメンタルサーチを作った
これは Vue.js #2 Advent Calendar 2017 の24日目です。
こんばんは、める(@c5meru)です。
日付まわっちゃいました、ごめんなさい…><
今回、あまり技術的なことを細かく書けない題材にしてしまったので、Qiitaではなく、はてブでカンタンに書かせていただきます。
なんでインクリメンタルサーチを作ったの?
自分が現在のお仕事で作っているサービスは、『JOB LIST』という、アルバイト・パートを中心とした求人情報のサイトです。
タウ◯ワークやバイ◯ルさんのような一般的な求人広告と、それに加えて、ユーザー投稿の「求人張り紙」が掲載されています。
あ、よかったらアプリから「求人張り紙」投稿してみてくださいね、ポイント集めるとAmazonギフト券にできるので。
それから、求人を出したい方は、こちらからセルフで作って無料で出すこともできますので、よかったらどうぞ。
と、サービスの宣伝はおいといて。
前々から、このサービスの検索部分で、インクリメンタルサーチを採用してみたいなーと思っていたのですが、諸般の事情で出来ずにいます。
とはいえ、いろんな予約サイトとかフリマ系アプリなどは、インクリメンタルサーチをガンガン使っているので、即時で検索ワードが見られるのって結構メリットなんじゃないかなーと思うのです。
インタラクティブなUIを、お仕事に関連するところで作ってみたいなーという気持ちはずっとあって、今年のうちに消化しちゃいたいな、と思って、作ってみました。
作ったもの
苦労したポイントは?
取り込むデータ形式
まあ、本当にお仕事でやるならAPIになるんでしょうけど、その場合も、どういうデータをやりとりするべきなのか、きっちり考える必要がありそう。
今回は漢字だけのサジェストで作りましたが、実際やるなら、ふりがなとかもサジェストできた方がいいですよね。
マルチキーワード対応
今回は愚直にsplit
と、マルチキーワードかどうかのフラグを用意して、、という感じで作りました。
時間がなくて実装しきれなかった、キーワード削除機能でも、結構ややこしくなりそうなところです。
複数のキーワード管理、もうちょっとうまいやり方がありそう。経験のある方に、知見をいただきたいです。
まとめ
インクリメンタルサーチを実装するのは初めてでしたが、Vue.js公式のドキュメントと、Codegridの記事がとても参考になりました。
パッと思いついたワードを打ち込むとソレっぽいワードが出てくるのは嬉しいし、制作陣が意図する検索方法と、ユーザーがやりたい検索方法が、うまい感じにマージできるのかな、と思いました。
あとは、まあ、時間がなかったので、けっこう突貫工事になってしまったな、という感じです。
最近Rubyに重きを置いていたので、もともとないJS力がさらに下がっており、些細な事で詰んでたりしました。反省。
来年はもっとレベルアップして、いい記事が書けるようにがんばります(`・ω・´)
『改訂第3版 すらすらと手が動くようになる SQL書き方ドリル』をやっています
これは 積読本 Advent Calendar 2017 の23日目です。
こんばんは、める(@c5meru)です。
今回積読本ということで、選んだ本は表題の通り、
『改訂第3版 すらすらと手が動くようになる SQL書き方ドリル』
という本です。
まず最初に、お詫びをさせてください。
この本、まだ全部おわってません…ごめんなさい(´・ω・`)
必ずや今年中に全部おわらせるぞ!という宣言とともに、途中までではありますが、取り組んでみた感想などなど、書いてみようと思います。
なんでSQLをやろうと思ったの?
会社でいろいろ教えていただいている@mikedaさんがインフラのほうに詳しい方で、クエリのパフォーマンスの話がよく出るので、チンプンカンプンじゃダメだな、と思った次第です。
あとはまあ、HTML、CSS、JavaScript、PHP、Rubyとやってきて、これといって特化したものがないのが悩みなのですが、ちょっと前に、Rubyをコアスキルにしたいな、と思うきっかけになる出来事がありまして、サーバーサイドをやっていくならSQL文は押さえておきたいな、と思いました。
どんな本なの?
SQL文のケースごとに小さな章がたくさんあって、それぞれ、例題→解説→練習問題、という順番で進んでいきます。
練習問題はSQL文の穴埋めからフリーテキストまで5問あり、高校数学の教科書・参考書みたいな感覚で、ノートを用意し、手で書いて覚えられるようになっています。
なんで積読になっちゃったの?
例題の解説で小さく備考として書かれていた要素がしれっと練習問題に出てきて、比較的序盤なのに分からないことが積み上がって、先に進むのがしんどくなってしまったためです。
あとは、ペンとノートを用意して作業環境を整えるのが(普段やってない分)意外とハードル高かったというのもあります。笑
やってみてどうだった?
アドベントカレンダーを書くにあたり、「備考もすみずみまで読む」「作業環境を整える」というハードルを乗り越え、章をいくつか進めてみました。
積読本になっている間、お仕事で集計のために何度かSQL文を(見よう見まねで)書いたこともあり、はじめからある程度わかる状態で始められたのはとても良かったです。
当たり前ですが「わかるようになると楽しい」というやつです。なので、なにもわからない初心者だとキツイ本だったのかも?
章の分け方はとても細かいので、チョットデキルくらいの人がケーススタディ的にやるのに向いてると思います。
自分は受験勉強を楽しんでたタイプだったので、ペンとノートで書いていくのは、それなりに楽しいです。普段やらなくなっちゃったから余計に。笑
逆に、ペンとノートで何かやるのが苦手な人には、向かないかもしれません。まあ、付録で学習用ソフトもついているので、そっちでやるといいのかも。
まとめ
そういうことで、本の紹介をさせていただきました。
わが家にはまだまだ積読本がたくさんあるので、年末年始も利用して、ガンガン読んでいこうと思います。