技術ブログ

(技術系中心)基本自分用備忘録なので、あくまで参考程度でお願いします。

Railsでファイル操作するとき

Railsでファイル操作するとき

Railsでファイル操作するときはDir.children(Ruby2.5以上で利用可能)ではなくrails.root.joinを利用する方が良い。

Dir.children実行時ファイルからの相対pathで取得してしまうので、実行箇所によって動かなくなるケースが稀にある。

一方rails.root.joinはrootディレクトリからの相対パスで取得できるので、実行個所によって動くなるケースがない。

参考サイト

Ruby 2.5新メソッド: Dir.children と Dir.each_child(翻訳)|TechRacho by BPS株式会社

Rails.root.join("foo", "bar")よりも、Rails.root.join("foo/bar")が良いのでは?というお話 - Qiita

個人開発でサービス名を決めるときに考慮すべきポイントまとめ

個人開発でサービス名を決めるときに考慮すべきポイントまとめ

個人開発でサービス名を決めるときに事前に考慮すべきポイント

  1. 既に同じような名前のサービスが存在しない
  2. 検索したときに強すぎるSEOサイトが存在しない
  3. 検索したときに問題のある(エロ系とか)がヒットしないか
  4. SNS系のアカウントでサービス名のアカウントが取得ができるかどうか

参考

個人開発における開発プロセスを公開してみる - Qiita

(vue.js) methods / computed / watchの比較表

(vue.js) methods / computed / watchの比較表

オプション名 methods computed watch
メソッド 算出プロパティ 監視プロパティ
使い方 一般的な関数と同様 return内に特定したいdataを含める(this.xxx) 特定したいdata名で作成コールバック関数含める
キャッシュ されない される される
実行タイミング 再描画の度に実行 特定data変更時、特定dataを元に派生したデータを使う時 特定data変更時、特定のコールバック関数を実行、非同期処理など

GASを利用してGoolgeForm回答があった時に自動連携でSlack通知する方法

GASを利用してGoolgeForm回答があった時に自動連携でSlack通知する方法

業務でGoogleFormを利用する部署があるのですが、GoogleFormでお客様問い合わせがあっても見逃してしまうケースが多いという相談を受けました。

そこで、GooleFormからお客様問い合わせがあったタイミングでSlackの通知チャンネルに自動通知できるシステムを構築してみました。

今回はその作業の流れを備忘録として残します。

手順説明

自分が実際に作業で行った流れをステップ毎に紹介します。

STEP1 「Slack側の設定」
STEP2 「GoogleForm側の設定」

step1 「SlackのIncoming WebHooks」を取得する

SlackでIncoming WebHooks※を登録します。

※WebhookとはWebサービスであるイベントが実行された時に外部サービスにPOSTリクエストを実行する仕組みの事です。

1. ワークスペース名のプルダウンを押すと、「設定と管理」が表示されるのでクリック
2. 「アプリを管理する」をクリック

すると、以下のようなwebページに遷移します。

appディレクトリに「incoming」と入力して検索をクリック

すると検索結果一覧に「Incoming Webhook」が表示されるので、選択します。

通知したいチャネルを選択して「Incoming Webhookインテグレーションの追加」を押すと、Webhook URL※が表示されるので保存しましょう。(このURLはあとでGASでプログラミングする時に利用します)

※ POSTリクエストするリクエスト先をWebhook URLと呼びます。

参考:SlackのWebhook URL取得手順

step2 Google Apps Scriptの作成

slackに通知するためのスクリプトを作成していきます。

スクリプトはGASを利用します。基本はJavascriptで書くことができます。

Slackと自動連携したいGoogleFormを開いて、スクリプトエディタを選択します。

すると、以下のようなGAS入力画面に移動するのでスクリプトを書いていきます。

スクリプト完成コード(GAS)

function sendToSlack(body, channel) {
  // STEP1で取得したWebhook URL
  var url = "https://hooks.slack.com/services/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";
  var data = { 
    // 通知先チャネル
    "channel" : channel,
    // ユーザー名称
    "username" : "問い合わせ通知",
    // Slackのメッセージを装飾 参考:https://qiita.com/daikiojm/items759ea40c00f9b539a4c8)
    "attachments": [{
      // 色
      "color": "#46D235",
      // 通知メッセージ内容
      "title": "google-formより問い合わせがありました",
      // attachmentの本文
      "text" : body,
    }],
  };
  // JavaScript のdataオブジェクトを JSON 文字列に変換
  var payload = JSON.stringify(data);
  // オプション内容
  var options = {
    // POSTリクエストで送信する
    "method" : "POST",
    // リクエストの Content-TypeをJSON指定
    "contentType" : "application/json",
    // payload指定
    "payload" : payload
  };
  // POSTリクエストを実行
  var response = UrlFetchApp.fetch(url, options);
}

function onFormSubmit(e){ 
  // 参考:https://qiita.com/ryo-yamaoka/items/7677ee4486cf395ce9bc
  var body = "<!here> 詳細情報\n";
  var applicant = "";
  // e.responseでFormResponseオブジェクトが取り出せます。そこからgetItemResponsesを呼び出し、ItemResponseの配列が取り出す
  var itemResponse = e.response.getItemResponses();

  for (var j = 0; j < itemResponse.length; j++){    
    var formData = itemResponse[j];
    // スプレッドシートのカラム名(googleフォームの質問)がtitle変数に代入        
    var title = formData.getItem().getTitle();
    // スプレッドシートのセルの値がresponse変数に代入
    var response = formData.getResponse();

  // Formの質問タイトルによって代入する値を変更する
  switch (title) {
      // 質問タイトルがメールアドレスの場合はmail変数にresponseを代入
      case "メールアドレス":
        mail = response;
        break;
      // 質問タイトルが電話番号の場合はnumber変数にresponseを代入
      case "電話番号":
        number = response;
        break;
      default:
        break;
    }
  }

  // 通知の際に表示する内容をbodyPublic変数に代
  var bodyPublic =  body + "メールアドレス:" + mail + "\n電話番号:" + number;
  // 通知したい内容(bodyPublid)と通知したいチャンネルをsendToSlack関数に渡して実行
  sendToSlack(bodyPublic, "#log-google-form-inquiry");
}

トリガーを設定します。

画面左側の選択項目からトリガーを選択

下記のトリガー設定項目から実行したい関数を選択。

今回の場合だとonFormSubmitを実行する関数に設定します。

今回はGoogleFormが送信されたタイミングでSlack通知して欲しいのでイベントのソースを「フォームから」を選択し、イベントの種類を「フォーム送信時」を選択。

まとめ

上記の作業を完了すれば、GoogleFormからお客様から問い合わせがあったタイミングでSlackに通知されるような仕組みになっているはずです。

Webviewまとめ

Webviewまとめ

■ Webviewとは

HTMLコンテンツを、アプリ(スマホ)内で表示できるようにするもの。

Webページは主にHTML という言語で作成されており、アプリ内でHTML を解析し、Webページのように表示することを可能にします。

■ Webviewのメリットは?

コスト面の削減ができる。

例えば既にWEB上にコンテンツがある場合はそれを流用してスマホアプリ開発すれば新規でプログラムすることなくアプリ上で同じコンテンツが表示できます。

■ ネイティブとの違いは?

ネイティブの方がサクサク・快適・スムーズな操作感を実現できます。

方ネイティブアプリでは、アプリ内にある程度のパーツを持っているので、画面遷移時の通信量を抑えることができ、よりなめらかで、サクサクした操作感を実現できます。また「画像が『ふわっと』表示される」というようなアニメーションもネイティブアプリならより自由に表現可能です。

ですのでユーザー体験にこだわるのであればネイティブで実装する方が良いです。

■ まとめ

Webviewは低予算で作成可能ですが、利用できる機能に制限がある

ネイティブは予算が高いが、利用できる範囲が広い

コスト重視 → Webview
UX重視 → ネイティブ

ちなみにWebviewはあくまで機能の一種であるため、ネイティブアプリに組み込むことができます。ネイティブアプリとWebviewを組み合わせたアプリは「ハイブリッドアプリ」と呼ばれます。

参考

教えて!Webviewって何?ネイティブと何が違うの? - MGRe(メグリ)

ウェブビュー(Webview)とネイティブアプリの違いをジャンル別で比較!【2022年最新!】

クラス/インスタンスメソッドの使い分け方法

クラス/インスタンスメソッドの使い分け方法

railsのモデルファイルを書いていて間違えやすいのが、クラス/インスタンスメソッドの使い分けです。

先に結論

データすべて(モデルそのもの)に対する操作はクラスメソッド。特定のデータに対する操作はインスタンスメソッド

例)Personモデルを定義したと仮定した場合

class Person
  # クラスメソッド
  def self.exists_no_name_person?
    no_name_person_list = Person.where(name: nil)
    no_name_person_list.exits?
  end

  # インスタンスメソッド
  def full_name
    self.first_name + self.last_name
  end
end

# exists_no_name_person?クラスメソッドは全てのPersonデータに対しての処理なのでクラスメソッドになる
Person.exists_no_name_person?

# full_nameインスタンスメソッドは特定のpersonにな対しての処理なのでインスタンスメソッドになる
tanaka = Person.new(name: 'tanaka')
tanaka.full_name

参考:

必要なModelファイルを作成する|RailsとReactでUberEats風SPAアプリケーションをつくってみよう!|Techpit

rails newでgit 管理外れる場合の対象方法

rails new git 管理外れる場合の対象方法

rails newで作成したアプリケーションのディレクトリに移行してみると、git initのコマンドを打ち込んでいないのにも関わらずgitの管理が始まってします。

このときの対処方法を記載する

例)こんな現象

[/Users/user_name]$ rails new testapp
[/Users/user_name]$ cd testapp
[/Users/user_name/testapp](master)$ 

対策方法

単純にgitの管理を破棄したいなら対象ディレクトリ内の.gitディレクトリを削除すればいいです。

  1. railsディレクトリ移動

cd sample-app

  1. ls -laで.git」というディレクトリを確認
$ ls -la
total 56
drwxr-xr-x  21 inouehiroki  staff   672  5 28 20:20 .
drwxr-xr-x   6 inouehiroki  staff   192  5 28 20:20 ..
drwxr-xr-x   9 inouehiroki  staff   288  5 28 20:20 .git <==== これ
-rw-r--r--   1 inouehiroki  staff   750  5 28 20:20 .gitignore
-rw-r--r--   1 inouehiroki  staff     6  5 28 20:20 .ruby-version
-rw-r--r--   1 inouehiroki  staff  1427  5 28 20:20 Gemfile
-rw-r--r--   1 inouehiroki  staff  3962  5 28 20:20 Gemfile.lock
-rw-r--r--   1 inouehiroki  staff   374  5 28 20:20 README.md
-rw-r--r--   1 inouehiroki  staff   227  5 28 20:20 Rakefile
drwxr-xr-x   8 inouehiroki  staff   256  5 28 20:20 app
drwxr-xr-x   7 inouehiroki  staff   224  5 28 20:20 bin
drwxr-xr-x  16 inouehiroki  staff   512  5 28 20:20 config
-rw-r--r--   1 inouehiroki  staff   130  5 28 20:20 config.ru
drwxr-xr-x   3 inouehiroki  staff    96  5 28 20:20 db
drwxr-xr-x   3 inouehiroki  staff    96  5 28 20:20 lib
drwxr-xr-x   3 inouehiroki  staff    96  5 28 20:20 log
drwxr-xr-x   3 inouehiroki  staff    96  5 28 20:20 public
drwxr-xr-x   3 inouehiroki  staff    96  5 28 20:20 storage
drwxr-xr-x   9 inouehiroki  staff   288  5 28 20:20 test
drwxr-xr-x   6 inouehiroki  staff   192  5 28 20:20 tmp
drwxr-xr-x   3 inouehiroki  staff    96  5 28 20:20 vendor
  1. rm -rfで削除

rm -rf .gitをすればitの管理下から外れます

参考

管理したいディレクトリの親ディレクトリでgit initしちゃったら? - Qiita