CSSだけでアコーディオンを実装する

僕はCSSが苦手なんですが、必要にかられてアコーディオンの実装をしたいということになり、少し前にCSS単体で実現できると聞いたのでやってみました。

  • CSS上級者はこんな実装しない
  • この実装はこういうときに困る

などありましたらご指摘いただければ嬉しいです。

動き

FAQページによくありがちです。

f:id:zuckey_17:20180702000417g:plain

実装

<div class="faq">
    <input type="checkbox" id="question1" class="checkbox" />
    <label for="question1">
        <div class="question">
            <span class="text">質問①</span>
            <span class="collapse-handle"></span>
        </div>
    </label>
    <div class="answer">
        質問①の答えです
    </div>
    <input type="checkbox" id="question2" class="checkbox" />
    <label for="question2">
        <div class="question">
            <span class="text">質問②</span>
            <span class="collapse-handle"></span>
        </div>
    </label>
    <div class="answer">
        質問②の答えです
    </div>
</div>
  .faq .question {
      height: 4em;
      display: flex;
      position: relative;
  }
  
  .faq label {
    display: block;
    cursor :pointer;
    transition: all 0.5s;
  }
  
  /* チェックボックスは表示しない */
  .faq input {
    display: none;
  }

  /* 開けることを示すための下矢印と答えをチェックボックスが入る前の状態にセット */

  .faq .collapse-handle {
    height: 0.7em;
    width: 1.5em;
    background: image-url("collapse_allow_close.svg") no-repeat;
    position: absolute;
    right: 1em;
    top: 40%;
  }
  
  .faq .answer {
    height: 0;
    padding: 0;
    overflow: hidden;
    opacity: 0;
    transition: 0.8s;
  }

  /* チェックボックスにチェックが入ったら、以下の要素が変更になる */
  
  .checkbox:checked + label .collapse-handle {
    height: 0.7em;
    width: 1.5em;
    background: image-url("collapse_allow_open.svg") no-repeat;
    position: absolute;
    right: 1em;
    top: 40%;
  }
  
  .checkbox:checked + label + .answer {
    height: auto;
    opacity: 1;
    background-color: #FAFAFA;
    color: #0A0E1F;
    display: flex;
    align-items: flex-start;
    padding: 1em 1em 1em 0;
  }

まとめ

意外と簡単にできました。
普段ならJSでやってしまいがちですが、CSSでやるのは新鮮でした。
これから頑張っていきたい気持ち💪

Railsの画像アップロードで必要に応じてCarrierWaveを回避したい

github.com

Ruby on Railsのフォームから画像をサーバにアップロードするというのを CarrierWave というGemを使って実装しています。

状況

ユーザー作成時に、基本的にはフォームからアバター用画像をアップロードさせるという簡単な実装で、もし画像の指定がなければそれを適用するというようなときにデフォルト画像を適用するということを実装しようとして少しハマったのでその回避方法を書いておきます。
Gemの中身を調べるということまで手が及んでいないので、回避方法が誤っているなどありましたら、指摘いただけると嬉しいです。

今回の僕の環境はRails 5.1です。

実装

実際には、S3へのデータアップロードなどをしていますが、今回は簡単のため、

  • name
  • image

f:id:zuckey_17:20180624233709p:plain:w200

を入力したら

  • Userのレコードが作成され
  • image にはファイル名が入り
  • 画像の実態はpublic/uploads に保存される

というような実装になっています。

# app/uploaders/user_image_uploader.rb

class UserImageUploader < CarrierWave::Uploader::Base
  storage :file
end

# app/models/users.rb

class User < ApplicationRecord
  mount_uploader :image, UserImageUploader
end

# app/controllers/user_controler.rb

  def create
    @user = User.new(user_params)
    
    respond_to do |format|
      if @user.save
        format.html { redirect_to @user, notice: 'User was successfully created.' }
        format.json { render :show, status: :created, location: @user }
      else
        format.html { render :new }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

上記のように書くだけで先程の要件を満たすことができます。

回避方法

f:id:zuckey_17:20180624234531p:plain

さて、今回実現したいことは単純で、public/uploads/default.pngUser.imageに指定したいということです。

実際は以下の方法でCarrierWavemount_uploader 回避しました。

# app/controllers/user_controler.rb

  def create
    @user = User.new(user_params)

    # imageに指定がないとき、デフォルト画像を使う
    @user[:image] = "default.png" if params[:image].nil?
    @user.save
    
    respond_to do |format|
      if @user.save
        format.html { redirect_to @user, notice: 'User was successfully created.' }
        format.json { render :show, status: :created, location: @user }
      else
        format.html { render :new }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

@user.imageに代入することはできず、ブラケットでの指定しか成功しませんでした。 もう少し中身を見て挙動を把握したいです。

Slack KPT Bot を簡単に導入できるように整備した

github.com

以前から作っていたGoogle Apps Script(GAS) + Google Spreadsheet によるKPT botを導入しやすくしました。

以下、READMEを日本語で

使い方

1. クローンして初期化

$ git clone git@github.com:zuckeyM-17/gas-kpt-bot.git
$ npm install
$ npm run login

2. Google Spreadsheetを作成

作成し、↓のようなURLを入手します。

https://docs.google.com/spreadsheets/d/【Google Spreadsheet ID】/edit#gid=0

3. Spreadsheetに紐付いたGASを作成

$ npx clasp create "slack kpt bot" "【Google Spreadsheet ID】"

4. SlackでIncoming Webhook のURLを入手し、index.jsを変更

ref: https://api.slack.com/incoming-webhooks

index.jsの1行目を修正します。

5. デプロイ

npm run deploy

6. GASのコンソール上で、スクリプトを公開する

ウェブアプリケーションとして公開

f:id:zuckey_17:20180610234629p:plain

設定

f:id:zuckey_17:20180610234638p:plain

POSTのためのURLを入手

f:id:zuckey_17:20180610234701p:plain

7. 上記で入手したURLをもとにOutgoing Webhookを設定

ref: https://api.slack.com/custom-integrations/outgoing-webhooks

トリガーとなる単語には以下を入れます。

K,P,T,k,p,t,start,end

参考

blog.zuckey17.org

blog.zuckey17.org

blog.zuckey17.org

blog.zuckey17.org

【GAS】Google Apps Scriptをコマンドラインからデプロイできる `clasp` の使い方

github.com

Google Apps Script(以下、GAS)をデプロイするときに、いちいちブラウザでコンソールを立ち上げ、コピペするのが嫌だなぁと思っていました。
また、コードの変更をGitで管理したいというような思いもあると思います。
claspはGASのデプロイやバージョン管理などの機能を提供してくれるコマンドラインツールです。
本エントリでは、その使い方を簡単に紹介します。

準備

$ mkdir gas-clasp && cd gas-clasp
$ npm init
$ npm i @google/clasp

公式のREADMEでは、グローバルにインストールするのが書かれていますが、npxでたたけば良いのでローカルで行います。

(参考)

blog.zuckey17.org

GASのAPI利用

https://script.google.com/home/usersettings

こちらにアクセスして、GASのAPI利用を可能にします。 f:id:zuckey_17:20180610175646p:plain:w300

Googleへのログイン

以下のコマンドで、Googleアカウントの認証を行います。

npx clasp login --ownkey

ブラウザが立ち上がり、認証が求められます。アカウントを選ぶと以下のように表示されるので「許可」を押します。

f:id:zuckey_17:20180610175232p:plain:w200

--ownkeyはカレントディレクトリに、.clasprc.jsonを作成するためのオプションで、つけないとホームディレクトリに配置されてしまいます。

スクリプトの作成

GASの作成には以下のコマンドを叩きます。

$ npx clasp create "スクリプトタイトル"
Created new script: https://script.google.com/d/【script id】/edit
Cloned 1 file.
└─ appsscript.json

上記の結果を見れば分かる通り、表示されたURLのGASを1つ作り、そこから設定ファイルとしてappsscript.jsonをダウンロードしてくれます。

また、このコマンドは裏で.clasp.jsonというファイルを作成しており、中身は作成したGASのscriptIdの値を示したjsonになっています。

その他の方法

Google Spreadsheetと紐付いたGASの作成

以前、このブログで

blog.zuckey17.org

Google Spreadsheet を GASから扱った事例を紹介しましたが、既存のGoogle Spreadsheet に紐付いた GASを作成したい場合は、そのGoogle SpreadsheetのIDを指定して作成することも可能です。

$ npx clasp create "スクリプトタイトル" "Google SpreadsheetのID"

そのIDは、SpreadsheetのURLの

https://docs.google.com/spreadsheets/d/【...この部分...】/edit

です。

既存スクリプトのクローン

また既存のスクリプトをクローンすることもできます。

$ npx clasp clone "スクリプト ID"

で、スクリプトIDは、GASページURLの

https://script.google.com/d/【...この部分...】/edit

です。

JavaScriptでのコードの記述とPush

今回はGASのコードについての説明は省略します。 以下のJavaScriptファイルを作成して、index.jsとして保存します。

function myFunction() {
   Logger.log('hello, world!');
}

この段階で以下のようなディレクトリは以下のようになっています。

 index.js
 appsscript.json
 .clasp.json
 .clasprc.json
 package-lock.json
 package.json
 node_modules

GASにアップロードするのは、index.jsappsscript.jsonだけなので、.claspignoreというファイルを作成して、アップロードするファイルを制限します。

**/**
!index.js
!appsscript.json

こちらを.claspignoreに保存します。

そして、以下のコマンドをたたけば、デプロイが完了します。

$ npx clasp push
└─ appsscript.json
└─ index.js
Pushed 2 files.

$ npx clasp deploy
Created version 1.
- 【バージョンのハッシュ】

すると、index.jsindex.gsとして登録されていることがわかります。

f:id:zuckey_17:20180610215116p:plain:w300

ここで実行ボタンを押し、⌘ + enterでログを確認すると、

f:id:zuckey_17:20180610215756p:plain

というのが確認でき、デプロイが成功していることがわかります。

まとめ

claspを使って、コマンドラインからGASをデプロイというのをやってみました。 簡単にできたので、これまで作っていたKPT Botをこれで簡単にデプロイできるようにしたいと思っています。

参考になれば嬉しいです!

感想、ご指摘などあれば、コメントもしくはTwitter @zuckey17まで連絡いただけますと嬉しいです!!

Slack KPT Bot 導入してから1ヶ月経ったので振り返りをしてみた

blog.zuckey17.org blog.zuckey17.org

このあたりのエントリで、Slackでの KPT Botを作成しました。

導入から1ヶ月くらい経ったので、振り返りたいと思います。

導入の経緯

入社して*1「なんか改善MTG」という打ち合わせが設定されていたのですが、みんながパラパラと共有事項を話して終わりでした。
改善MTGということなので、なにか問題を見つけて改善できるものにしたいなと思いました。

急激に人が増えたこともあり、*2業務上の単なる会話ではなく、もっとお互いを知っていけるような会話を増やしたい(というより、僕がチームの人を知っていきたい)という気持ちもありました。

Botに優しさを求める

はじめ、Botのアイコンは、Slackデフォルトのロボットアイコンでしたが、投稿したときにテンションが上がらない、ということでかわいいタレントさん*3をアイコンに設定するという案を投げたところ、吉岡里帆さんという名前が上がりました。

f:id:zuckey_17:20180607081457p:plain:w300

さらに、registering.... 受け付けました!というのがあまり愛がない、という意見も出ました。

f:id:zuckey_17:20180607084705p:plain:w300

なので振り切ってめちゃくちゃ可愛くしたところ、

f:id:zuckey_17:20180607085444p:plain:w300

キャピキャピしすぎて見るのが辛い、との指摘を受け、最終的には↓の感じに収まりました。

f:id:zuckey_17:20180607085108p:plain:w300

改善の早さもKeepで褒められました。

f:id:zuckey_17:20180607085700p:plain:w300

チーム全員でのデバッグ

チームは全員開発者なので、デバッグも全員でやりました。
Bot開発に伴う言語の処理について、諸先輩方が優しく教えてくださいます😇

f:id:zuckey_17:20180607090352p:plain:w200

f:id:zuckey_17:20180609022955p:plain:w400

f:id:zuckey_17:20180609023014p:plain:w400

勉強になりますね。

Keepで拍手しながら進めると楽しい

Keepは良かったことを「良かったよね」と確認することができるので、拍手して進めます。
せっかく機能をリリースしたのにそれを喜ばないのは寂しいし、良いことをすれば「よかったよ」と言われたいものです。
また、このKPT BotはKeep => Problem => Tryの順にまとめてくれるので、振り返りのはじめにこれでテンションを上げていくというのは、その場に馴染むことができるという意味で成功でした。

ちょっと強引でも良いからかさ増しする

よくKPTで問題に挙げられると思うのですが、SlackでのKPTでもやはり普段から意識しないとあまり数がたまらないです。
なので、導入した僕が積極的にくだらないことをKPTに載せたり、裏でこういうことを書いとけばいいんじゃない、とか、新卒のエンジニアにとりあえずなんでもいいから1つ書くように言ったりしてました。
*4 項目が多いだけで活発感が出るので非常に良いです。

まとめ

KPT、入社すぐの僕が導入するのはやはり少し抵抗がありましたが、実際やってみて

f:id:zuckey_17:20180609023310p:plain:w300

というKeepを上げていただいたり、

f:id:zuckey_17:20180609023512p:plain:w400

という感じで、業務や環境だけでなく、振り返りの会自体も改善していっているので、導入してすごく良かったなと思えました。

当初個人的に目標だったチームの人のことを知る、というのも小さなところから良いと思ったこと、悪いと思ったこと、ちょっとした挑戦をカジュアルに知れて、仲良くなれた気がしました。
みなさんもぜひやってみては、いかがでしょうか??

*1:3月末入社でした

*2:4ヶ月で2倍!!

*3:チームは悲しいことに現在男性ばかりなのです。本当はキャラクターとか作りたい

*4:この根回しは全員の前で暴露されましたがw

しがないラジオMeetup 1を開催しました!

shiganai.connpass.com

開催しました。
総勢40数名の方に来ていただき、本当に感謝です。
参加してくださった方々本当にありがとうございました。

Podcastはリスナーの可視化が難しいとは聞きますが、2017年の3月から始めて1年2ヶ月でここまで多くの方に支えていただいているのだなと再認識し感動しました。

細かいまとめなどは、togetterや参加者の方々がまとめてくださっているので、そちらを参照ください。

togetter.com

twitter.com

また、編集を言い訳にほとんど何もしなかった僕に変わって、この会を企画から準備までしてくれた gamiさん、本当にありがとうございました。

これからも、さまざまな「しがない」エピソードをお届けしていくつもりですので、応援よろしくおねがいします。

法律はイノベーションを加速させる! Studios session #3「時代を進めるルール」に参加してきた

www.facebook.com

Studios sessionとは、僕の所属するツクルバのtsukuruba studiosが主催するセッションイベントです。
第3回となる今回は*1弁護士・水野祐さんによる「時代を進めるルール」というテーマのセッションでした。

モチベーション

はじめ法律とクリエイティビティというと、「オープンソースのライセンス問題で大きい会社が大変そうだよなぁ」ということくらいしかイメージが働かず、どういうことが話されるのだろう?と思っていました。
そんな法律に疎い僕でも、「様々なビジネスモデルの企業が法律を味方につけたり、法律をうまく変えたりしながら、どのように成長していったか」といった話など、すごく興味深い内容が多かったのでセッションの一部と感想を共有したいと思います。
詳しい内容については後に、現在開発中のtsukuruba studiosのメディアにて公開されるかと思いますのでそちらを参照いただければと思います。*2

Who is 水野 祐

twitter.com

法律家・弁護士(シティライツ法律事務所、東京弁護士会)/Arts and Law理事/Creative Commons Japan理事/慶應義塾大学SFC研究所上席所員(リーガルデザイン・ラボ)/グッドデザイン賞審査員 ※ Twitterプロフィールより引用

弁護士として新しい技術やビジネスに関わりのある企業を法律で加速させる、ということに取り組まれているらしく、ツクルバの顧問弁護士としても入っていただいており、利用規約にサービスメッセージを入れるといったこともされていて面白いなと思いました
昨年「法のデザイン」という本も出されており、お話の中でも度々その中の事例についての言及がありました。

法のデザイン?創造性とイノベーションは法によって加速する

法のデザイン?創造性とイノベーションは法によって加速する

法律をビジネスを規制するものではなく、加速させるものと捉え、世の中に仕掛けていくビジネスをされている方々がリスクヘッジではなく業界を開拓する方法としての法律の利用という文脈で相談に来られたりする、ということのようです。

会の構成

  1. チェックイン / ツクルバ および tsukuruba studios の 説明
  2. 水野祐さんによる自己紹介 兼 ビジネスと法律についての導入
  3. キーワードをベースにしたセッション

という構成で、司会はツクルバCCOの@maa20XXで進みました。

1. チェックイン / ツクルバ および tsukuruba studios の 説明

チェックインというのは、参加者同士で行ういわゆるアイスブレイク的なもので、ツクルバではある「場」に溶け込むという目的でよく行われます。
知がめぐり、人がつながる場のデザイン」という本を紹介しつつ、「聞く、考える、対話する、気づく」というのを意識して社内外の参加者で自己紹介や何を考えて参加しているのかを共有しました。

僕は前述の通り、面白そうだけどよくわからんなあなどと思っていたので、水野さんをもともと知ってらっしゃった方から、弁護士の枠を超えたクリエイターらしいということを聞いてその時は更に「?」となりました笑

2. 水野祐さんによる自己紹介 兼 ビジネスと法律についての導入

水野さんによる自己紹介はイコール、新しいビジネスと法律との関わりという大きなテーマの紹介、導入でした。

面白かったトピックをかいつまんで紹介すると、

  • 契約書のUI/UX
    • 契約書にはカルチャーが反映される
    • NIKEGoogle
  • 法律は縁遠くなく、身近なルールの延長線上
    • 変化を前提に民間や企業がルール形成に参加する
    • ルール形成による新市場創出
  • 米国IT企業の公共政策部
    • グレーゾーン = 現在の社会が抱える課題を発見し解決するきっかけ
  • ハリル・ホッジ* アーセン・ベンゲル対談
    • 日本人サッカーには球際とずる賢さが足りない
    • ルールを自分なりに解釈するのは知性の証明

というようなことが紹介されていました。

これを聞いた直後の感想としては、スタートアップでサービス開発をしている僕にとって、法律やルールというのは思っていたよりも遠い存在ではないのだな、ということでした。
以前、僕はアプリ制作のプラットフォーム的な会社に所属しており、iTunesストアに並ぶアプリを数多く作っていた時期がありました。
そのアプリが量産型であったり、Appleが独自に定義したアプリ的な動きをしなかったり、ポリコレに反しているものであったりすると、審査が通らない、たとえ既に出ているアプリであってもiTunesからアプリを落とされる、という危険性がありました。
その会社では、プラットフォームによって生成されるアプリが上記のような(明文化されていないものも含めて)規約に違反しないような様々な工夫によってそういった事象は僕の知る限りほとんどありませんでした。
そういう工夫は、視点を変えれば、法律やルールを理解して逆に他社との競合優位性に変えていくというプロセスに近かったのだな、と思いました。

まだ入って間もないツクルバですが、現在主に軸足をおいている不動産というドメインは法律だけでなく、独自のルールや慣習などが多い印象を持っています。
そのなかでどうHackしていくのか、というのはこれから中で工夫していける部分だな、と思いました。

3. キーワードをベースにしたセッション

会の後半は、事前のピックアップ + その場での挙手によるキーワードをベースにした質問大会でした。

ネタとしては、

  • オマージュとパクリの境界線
  • ビジネスと遊び心の折り合い
  • 新たなルールの伝播について
  • 法律のプロへの相談が藪蛇になるパターン

などがありどれも面白かったです。

特にcowcamoというメディアを運営しているという性質上、社内からは

  • 著作権について: オマージュとパクリの境界線
  • 不動産広告としての記事と楽しませる記事の折り合いについて: ビジネスと遊び心の折り合い

の質問がありました。

この話の中で印象深かったのは、著作権においても、不動産広告のルールにおいても、当たり前のことを当たり前にした上で、いろいろなテクニックがあるということを紹介していただきました。
特に、不動産広告は特にルールの多い分野ということもあり

  • 法律についての正しい理解のために法律を作る人たちと議論をする
  • 不動産広告という名前ではなく法律の余白をついた新たな概念、名前付けをする
  • 作る際のポリシーを明文化で多少のクレームに動じなくなる

などが主に挙げられたかなと思います。
セッションという名前でもあったとおり、議論が巻き起こっており、実際社内でも何らかの動きがとれそうだという話になっていました。

まとめ

これまで書いてきませんでしたが、この会は社内外含めて20人くらいの規模で行われていました。
はじめのチェックインではぎこちない空気もありましたが、お話が面白かったのか、お酒も少し入っていたのか*3、最後にはかなり盛り上がり、終了してから1時間半位も各所で議論に花が咲いていて、良い雰囲気の会となっていました。

冒頭にも上げたとおり、はじめはピンと来ていなかった僕ですが、エンジニアは仕組みを作る側の人間だと思うので、既存の仕組みのファジーな部分に切り込んで、面白いシステム開発ができるようなエンジニアになりたいものだと思いました。
また僕がツクルバに入った理由として、IT技術に終始しないサービスの問題解決ができるエンジニアになりたいという思いがありました。
不動産業界はレガシーな業態で法律・ルールも入り組んでいるということなのでそれをしっかり把握しつつ新たな価値を提供していけたらな、というモチベーションに繋がった良い会でした。*4

告知

studios session

tsukuruba studiosでは、今後も1ヶ月に1回くらいのペースでいろいろな方を呼んでセッションしていく予定です。この規模が良いということもあって大体的に告知をしていないので、もし興味がある方は、ツクルバのFBページにいいねしていただけると、いち早く情報を受け取れるかと思います。

ちなみに、過去2回は↓のようなテーマでした。

Studios session #1「異質性とクリエイション」/ with 宇田川 元一 氏 Studios session #2「協創するチームはいかに生まれるか」/ with 安斎 勇樹 氏

ツクルバはメンバーを募集しています

ツクルバでは、エンジニアに限らずいろいろな職種で一緒に働くメンバーを募集しています。
自分と違った職能、性質の人たちと仕事ができて、かつ対面でもテキストでもコミュニケーションがすごく活発でうまい人が多いという印象です。
詳しくは↓を見ていただくか、個別に僕まで連絡いただければと思います。

tsukuruba.com

感想、ご指摘などあれば、コメントもしくはTwitter @zuckey17まで連絡いただけますと嬉しいです!!

*1:これまではjoinする前と直後で開催を知らなかったのです

*2:こちらにもリンクを張ります

*3:質問項目の事前仕込みが功を奏したのか

*4:あまりどこでも転職の告知をしていなかったので、意気込み発表みたいになってしまいました💦