Madogiwa Blog

主に技術系の学習メモに使っていきます。

Ionic:Dockerでionic開発環境を作る🐳

こんにちは、まどぎわです(・∀・)
最近またionicを触りはじめて、環境構築する際にローカルではなく、 Dockerを使ってみたのでそのやり方をメモしておきますφ(・

ちなみに私の環境は、下記の通りです。

種類 バージョン
OS MacOS High Sierra 10.13.6
Docker 18.06.1-ce-mac73 (26764)

やり方は結構簡単です🙌

まずはDockerHubでionic用のコンテナを探します🐳

https://hub.docker.com/

いろいろ出てきますが、私は下記を使いました👀

https://hub.docker.com/r/beevelop/ionic/

これを使って下記のようなDockerfileを作りました。

FROM beevelop/ionic:latest
ENV WORK_DIR /work
RUN mkdir ${WORK_DIR}
WORKDIR ${WORK_DIR}

※やってることは作業用のディレクトリを作って、そこをWORKDIRにしているだけです。

このDockerfileを任意のディレクトリに配置して下記を実行します🐳 そうするとコンテナ上の/workに作業用ディレクトリがマウントされて、ionicの開発環境が立ち上がります。

# ionic-workはコンテナ名なので、任意の名前に変える
$ docker build -t ionic-work .
# `/Users/user_name/Documents/repo/ionic/work`は適宜変える
# デフォルトのionicアプリ起動時のポート番号(8100)にアクセスできるように`-p`でホストの8100を割り当て
$ docker run -v /Users/user_name/Documents/repo/ionic/work:/work -p 8100:8100 -d -it --name ionic-work ionic-work
$ docker exec -it ionic-work bash

これでDockerコンテナ上の開発環境に接続することが出来ました🙌

アプリを作成して、下記を実行すれば、、、

$ cd アプリのルートディレクトリ
$ ionic serve

http://localhost:8100/をブラウザで開くとアプリが起動しているはずです👀
結構簡単ですね🙌

Dockerコンテナで開発環境が作れると、作成と破棄が簡単に出来るので良いですね。みなさんもIonic環境を作るときは試してみてくださいm( )m

参考

qiita.com

Vue.js: 異なるVueインスタンスのdataの値を取得する方法

下記のような2つのVueインスタンスあり、別のVueインスタンスのdataの値を参照したいときに少しハマったので、ちょっとバッドプラクティス感ありますが対応方法をメモメモφ(・

結論としては、下記のようにすればできた🙌
参照したいVueインスタンスを変数に入れといて、その変数からdataを参照して返却するメソッドを定義してあげれば良いみたい👀

let hoge = new Vue({
  el: '#hoge',
  data: {
    val1: 'val1',
    val2: 'val2'
  }
})

let fuga = new Vue({
  el: '#fuga',
  data: {
   val3: 'val3'
  },
  methods: {
    hogeVal1: function () {
      // hogeのval1をfugaで参照出来る
      retuern hoge.val1
    }   
  }
})
<div id="fuga">
  <span>{{hogeVal1()}}</span>
</div>

なんかもうちょっと良いやり方ありそうですが、とりあえず出来たので書いてみました(;・∀・)

bashでgitのコマンドのtab補完を有効にする方法

みなさん、こんにちは。まどぎわです(・∀・) 最近bashを使ってfishを使って、またbashに戻ってきました。いろいろ調べてみると結構bashでもいろいろ出来るみたいですね👀

bashだとMacのデフォルトで入ってるし、いろいろ出来るのであれば環境構築が要らないbashを使えると良いですよねということで、 今日はbashでgitコマンドの補完が、すごい簡単に出来るので、そのやり方をメモしておきますφ(・

やりかた

まず、gitコマンドの補完にはgit-completion.bashが必要です、おそらくデフォルトで入っているとおもうので、下記コマンドでファイルのパスを確認しておきます。

$ find / -name "git-completion.bash"
=> /Library/Developer/CommandLineTools/usr/share/git-core/git-completion.bash

その後.bashrcに書きを追記します。

source /Library/Developer/CommandLineTools/usr/share/git-core/git-completion.bash

そうすると、こんな感じでtab補完が使えるようになります。 f:id:madogiwa0124:20180901175057g:plain
※変わらない場合は、source ~/.bashrcを実行してみてください。

以上です、めっちゃ簡単ですね🙌

参考

qiita.com

【Rails】Webpackerを使ってRailsにフロントエンド開発環境を作ってみた

みなさん、こんにちは。まどぎわです(・∀・)
今日は、RailsアプリにWebpackerを使って、フロントエンド環境を整えて少し開発してみたので、そのあたりをブログに整理しておこうと思います🙌

WebPackerとは?

WebPackerとは、RailsでWebpackをいい感じに扱うことができる機能です。
私もまだ全然理解が足りてない部分がありますが、公式ドキュメントや下記にまとまってますので、興味がある方は読んでみてくださいm( )m

github.com

techracho.bpsinc.jp

今回やったこと

今回は私の開発している「Quizアプリ Quiq」に評価機能を作ってみました。

こんな感じ
f:id:madogiwa0124:20180826181920g:plain

下記から実際に触ることができます🙌

quiz-quiq.herokuapp.com

Webpackerの導入手順

Gemfileに書きを追記してbundle installを実施

gem 'webpacker', github: 'rails/webpacker'

その後、webpackervueをinstallします。

bundle exec rails webpacker:install
# 下記は導入したいフレームワークに合わせて修正してください。
bundle exec rails webpacker:install:vue

これで、bin/webpackでwebpackのビルドが走るようになり、railsでvueを扱えるようになります(・∀・)

フロントエンドの実装

今回は下記のような機能をRails上にVue.jsを使って実装しました。 デフォルトのルールでは、下記のようなディレクトリ構成で実装していきます。
(vue.jsの実装の仕方等は、tutorial等が充実してますので、そちらをご確認ください。)

# viewから読み込むEndpoint
app/javascript/packs
# その他
app/javascript

実際に私が書いたコードが下記です(お見苦しいかもしれません。。。)

QuizLike.vue

ここでは、実際のVueコンポーネントを実装してます。rails側へのpost処理等を実装してます。

<template>
  <div style="text-align: right">
    <button class="btn btn-success btn-sm" @click="create(1)"><i class="fas fa-thumbs-up"></i></button>
    <button class="btn btn-danger btn-sm" @click="create(-1)"><i class="fas fa-thumbs-down"></i></button>
    <span class="text-secondary">評価 : {{ like_count }} pt</span>
  </div>
</template>

<script>
import axios from 'axios';
import { csrfToken } from 'rails-ujs'
axios.defaults.headers.common['X-CSRF-Token'] = csrfToken()
export default {
  data: function () {
    return {
      like_count: this.init_like_count
    }
  },
  props: {
    init_like_count: {
      type: Number,
      required: true
    },
    quiz_id: {
      type: Number,
      required: true
    }
  },
  methods: {
    create: function (value) {
      this.like_count += value
      axios.post(`/quizzes/${this.quiz_id}/like`, {
        like: { value: this.like_count }
      });
    }
  }
}
</script>

packs/quizzes.js

ここでは、作成したコンポーネントの読み込み、Vueインスタンスの作成を行うEndpointを定義してます。

import Vue from 'vue/dist/vue.esm'
import QuizLike from '../QuizLike.vue';

new Vue({
  el: '#like_area',
  components: { QuizLike },
})

result.html.haml

ここでは、javascript_pack_tagを使って、Endpointの読み込みをおこなっています。

= javascript_pack_tag 'quizzes'

point

railsにpostする

railsにpostを送るときには、axiosを使用するの結構メジャーみたいです。
初めて使ってみましたが、下記のようにjsonでパラメーターを作成して簡単にpostがおくれました🙌

axios.post(`/quizzes/${this.quiz_id}/like`, {
    like: { value: this.like_count }
});

postする際の注意点

特に何も考えずにpostメソッドを送ろうとすると、RailsCSRF対策に引っかかり、InvalidAuthenticityTokenが発生してしまいます。Vueコンポーネントからrailsにpostする場合は、下記のように明示的にTokenを作成し、headerに付与してあげる必要があります👀

import axios from 'axios';
import { csrfToken } from 'rails-ujs'
axios.defaults.headers.common['X-CSRF-Token'] = csrfToken()

Tips

上でも少し触れましたが、いろいろハマったところをtipsとして、対応方法を軽くですがメモしておきますφ(・

Uglifier::Error: Unexpected token

下記Issueを参考にproduction.rbを修正して対応しました。

config.assets.js_compressor = Uglifier.new(harmony: true)

github.com

Module build failed: ReferenceError: Unknown plugin "@babel/plugin-transform-destructuring"

下記Issueを参考にyarn add https://github.com/rails/webpacker.gitを実行して対応しました。

Module build failed, Unknown plugin "@babel/plugin-syntax-dynamic-import" after webpacker:install:vue · Issue #1565 · rails/webpacker · GitHub

herokuデプロイ時にnode系のmodule fetchで500Errorで落ちる

何回かリトライしたら正常終了しました。

おわりに

今回はWebpacker使って、フロントエンド開発環境を作ってみました。
良いんだか悪いんだかわからないですが、webpack等フロントエンド関連技術をしらない自分でも結構簡単にフロントエンド環境を作ることができました🙌

これからはフロントエンド技術も学んで、よりユーザーに優しいサービスを作っていきたいです👀

参考

top-men.hatenablog.com

qiita.com

tech.medpeer.co.jp

【開発効率UP】Emacsキーバインドでコンソール操作を快適にしよう!

みなさん、こんにちは。まどぎわです(・∀・)
コンソール操作って結構めんどくさいですよね。。。

例えばコマンドを打ち間違えてしまった場合、普通にやると下記のようになるんじゃないかな?と思います。

f:id:madogiwa0124:20180819183742g:plain

しかしEmacsキーバインドを使うと、下記のように修正できます(・∀・)

f:id:madogiwa0124:20180819183715g:plain

上と比べてみても結構快適そうですよね?🙌

実際に開発してるときは、コンソールで操作してるときも多いと思うので、コンソール操作を効率的に行えると開発効率も上がるんじゃないかなと思います。

Emacsキーバインドは、MacのPCであればで特にインストール等を不要で使えますし、コンソールだけじゃなくてブラウザ操作やEditorでも使えるので、ぜひ使ってみてください(・∀・)

Emacsのよく使うコマンド

よく使いそうなコマンドを下記に記載してみました、Emacsにはまだまだいろいろなコマンドがありますが、とりあえずコレだけ覚えておくだけでも大分快適になるんじゃないかな?と思います👀

コマンド 動作
ctrl + f 次の文字へ
ctrl + b 前の文字へ
ctrl + n 次の行へ
ctrl + p 前の行へ
ctrl + a 行頭へ
ctrl + e 行末へ
ctrl + k カーソル以降を削除

fとかbとかnとか一見覚えにくいなぁと思いますが、fはforward、bはback、nはnextと、意味から推測出来る単語の頭文字を取っているので、使っていると自然に覚えやすいと思います🙌

ちなみに、最初の例は下記のような操作を行っています。

  1. 入力ミス
  2. ctrl + aで行頭へ移動
  3. ctrl + fで修正部分まで移動
  4. 訂正し、再実行

f:id:madogiwa0124:20180819183715g:plain

EmacsキーバインドをEditorで使う

Emacsキーバインドを覚えるとEditorでも使いたくなってしまうのですが、メジャーなEditorにはだいたいEmacsキーバインド拡張機能があるようです。みなさんも使ってみては?👀

おわりに

今日は、コンソール操作を効率化する方法としてEmacsキーバインドを紹介しました。

コマンドも意味のある名前の頭文字になっていて、インストール不要で使えるので、そこまで学習コストを掛けずに覚えられるので、開発効率UPになるんじゃないかと思います!(・∀・)

みなさんも、是非使ってみてください🙌

参考

Emacsのキーバインド覚書

qiita.com

qiita.com

Ruby:ログ出力を支援するsppというgemを作ってみた💎✨

こんにちは、まどぎわです(・∀・)
今回はsppというログ出力を支援するGemを公開したので、それについて書こうと思います🙌
(ちなみに初めてRubyGemsにコードを公開してみました...!)

ちなみに今回リリースしたGemは下記です。

spp | RubyGems.org | your community gem host

github.com

使い方はこんな感じ

Spp::spp('hoge')
=>
========== START ==========
"hoge"
========== E N D ==========

使う前には、Gemfileに下記を追記するか、gem install sppを実行するだけです👀

gem 'spp'

ログを見ながらデバッグするときとか、こんな感じに便利かなぁと思います(..)
下記のような感じでやると取得したユーザー一覧の取得処理をログ上で目立たせることができます🙌

  def index
    @quizzes = if params[:search_text]
                 Quiz.includes(:choices).search(params[:search_text])
               else
                 Quiz.includes(:choices)
               end
    Spp::spp(@quizzes.pluck(:title).uniq)
  end

こんな感じで目立つ(・∀・)

========== START ==========
["テスト", "タイトル", "HUNTERXHUNTERクイズ", "プロレスクイズ", "テストあああ", "私についてのQuiz"]
========== E N D ==========

ちなみに下記のような感じで、修飾をカスタマイズすることもできますφ(..)

  def index
    @quizzes = if params[:search_text]
                 Quiz.includes(:choices).search(params[:search_text])
               else
                 Quiz.includes(:choices)
               end
    Spp::spp(@quizzes.pluck(:title).uniq, '開始', '終了', '' * 5)
  end

こんな感じ(・∀・)

⚡⚡⚡⚡⚡ 開始 ⚡⚡⚡⚡⚡
["テスト", "タイトル", "HUNTERXHUNTERクイズ", "プロレスクイズ", "テストあああ", "私についてのQuiz"]
⚡⚡⚡⚡⚡ 終了 ⚡⚡⚡⚡⚡

内部的にはシンプルで、下記コードが実行されているだけなのですが、毎回書くのがめんどくさかったのでGemにしてみました🙌

puts "========== START =========="
pp 'hoge'
puts "========== E N D =========="

ちなみにこんな感じで書くと、

  def index
    Spp::spp_bench do
      @quizzes = if params[:search_text]
                  Quiz.includes(:choices).search(params[:search_text])
                else
                  Quiz.includes(:choices)
                end
      @quizzes.pluck(:title).uniq
    end
  end

ベンチマークも取れます💪

========== START(2018-08-09 22:12:16 +0900) ==========
   (5.1ms)  SELECT "quizzes"."title" FROM "quizzes" LEFT OUTER JOIN "choices" ON "choices"."quiz_id" = "quizzes"."id"
  ↳ app/controllers/quizzes_controller.rb:12
["テスト", "タイトル", "HUNTERXHUNTERクイズ", "プロレスクイズ", "テストあああ", "私についてのQuiz"]
========== E N D(2018-08-09 22:12:16 +0900) ==========

同じように修飾もできます(・∀・)

⚡⚡⚡ START(2018-08-09 22:15:06 +0900) ⚡⚡⚡
   (1.3ms)  SELECT "quizzes"."title" FROM "quizzes" LEFT OUTER JOIN "choices" ON "choices"."quiz_id" = "quizzes"."id"
  ↳ app/controllers/quizzes_controller.rb:12
["テスト", "タイトル", "HUNTERXHUNTERクイズ", "プロレスクイズ", "テストあああ", "私についてのQuiz"]
⚡⚡⚡ E N D(2018-08-09 22:15:06 +0900) ⚡⚡⚡

みなさんも良かったら使ってみてくださいm( )m

ソースコードや詳しい使い方はこちら github.com

Gemの作り方

Gemの作り方は下記記事を参考にさせて頂きましたm( )m
意外と簡単に作れるので、みなさんも作ってみては?🙌

morizyun.github.io

qiita.com

masarakki.github.io

ハマったところ

一応gem公開時にハマった箇所もメモしておきますφ(..)メモメモ

rake release時の権限Error

bundle exec rake release実行時に下記のようなErrorが出てハマりました(T_T)

You do not have permission to push to this gem. Ask...

原因は、単純にgemの名前が重複していて、既存のgemにpushしようとして権限Errorになってました。。。
重複しないようにコードの内のgemの名前を指定している箇所を置換して解決しました。

Ruby:mini_magickを使って画像に文字(テキスト)を合成する

みなさん、こんにちは。まどぎわです(・∀・)
今日は、mini_magicと使って画像にテキストを合成する方法をメモしておきますφ(..)

mini_magicを使うと某匿名質問サービスみたいに画像に文字を合成する機能を結構簡単に作ることが出来ます🙌

↓公式のリポジトリはこちら↓

github.com

mini_magicの使い方

準備

mini_magicを使うには、ImageMagickというアプリがインストールされている必要があります。 まずはインストールされているかどうか確認してください。

$ convert -version
Version: ImageMagick 6.9.9-40 Q16 x86_64 2018-07-14 http://www.imagemagick.org
Copyright: © 1999-2018 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Features: Cipher DPC Modules
Delegates (built-in): bzlib freetype jng jpeg ltdl lzma png tiff xml zlib

インストールされていなかったかたは、「ImageMagick インストール」等でググッってインストールしてください(..)

mini_magicのインストール

mini_magicも通常のGemと同じようにGemfileに追記するか、下記コマンドを実行することでインストールすることが出来ます。

gem 'mini_magick'

文字列を受け取って画像を生成してみる

背景画像を準備

まずは文字列を埋め込む背景画像を用意します。今回は、こんな感じのを用意しました。 f:id:madogiwa0124:20180721163042p:plain

文字列を受け取って画像に合成する処理を作ってみる

実際の実装を下記に記載しておきますφ(..)

class ImageHelper
  require 'mini_magick'
  require 'securerandom'

  BASE_IMAGE_PATH = './app/assets/images/bg_image.png'.freeze
  GRAVITY = 'center'.freeze
  TEXT_POSITION = '0,0'.freeze
  FONT = './app/assets/fonts/komorebi-gothic.ttf'.freeze
  FONT_SIZE = 65
  INDENTION_COUNT = 11
  ROW_LIMIT = 8

  class << self
    # 合成後のFileClassを生成
    def build(text)
      text = prepare_text(text)
      @image = MiniMagick::Image.open(BASE_IMAGE_PATH)
      configuration(text)
    end

    # 合成後のFileの書き出し
    def write(text)
      build(text)
      @image.write uniq_file_name
    end

    private

    # uniqなファイル名を返却
    def uniq_file_name
      "#{SecureRandom.hex}.png"
    end

    # 設定関連の値を代入
    def configuration(text)
      @image.combine_options do |config|
        config.font FONT
        config.gravity GRAVITY
        config.pointsize FONT_SIZE
        config.draw "text #{TEXT_POSITION} '#{text}'"
      end
    end

    # 背景にいい感じに収まるように文字を調整して返却
    def prepare_text(text)
      text.scan(/.{1,#{INDENTION_COUNT}}/)[0...ROW_LIMIT].join("\n")
    end
  end
end

こんな感じで、使うことが出来ます(・∀・)

# 生成した画像のFileClassを取得
ImageHelper.build('何かしらの文字列を合成してみる').tempfile.open.read
# 生成した画像の書き出し
ImageHelper.write('何かしらの文字列を合成してみる')

↓出来た画像がこちら↓ f:id:madogiwa0124:20180721164012p:plain

おわりに

設定周りのやり方を調べるのに結構苦労しましたが、実装は意外とシンプルですね(・∀・)
ちなみに私も最近作ったサービスでも使ってみました🙌
↓みたいなQuizを投稿して画像でシェア出来るサービスです(・∀・) quiz-quiq.herokuapp.com

参考資料

keruuweb.com

github.com