ホーム ブログ ページ 19

【Rails】I18nの言語データをDBから取得【i18n/i18n-active_record】

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

I18nの言語データをymlではなくDBから取得する方法を記述します。

準備

1.Gemfileに追記してbundle install

Gemfile

gem 'i18n-active_record', :require => 'i18n/active_record'

2.migrateファイル作成

$ bundle exec rails g migrations CreateTranslations locale:string key:string value:text interpolations:text is_proc:boolean
class CreateTranslations < ActiveRecord::Migration
  def self.up
    create_table :translations do |t|
      t.string :locale
      t.string :key
      t.text   :value
      t.text   :interpolations
      t.boolean :is_proc, :default => false

      t.timestamps
    end
  end
end

3.config/initializers/i18n_active_record.rbの作成

require 'i18n/backend/active_record'

Translation = I18n::Backend::ActiveRecord::Translation

if Translation.table_exists?
  I18n.backend = I18n::Backend::ActiveRecord.new

  I18n::Backend::ActiveRecord.send(:include, I18n::Backend::Flatten)
  I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)

  # 一度呼んだkey,valueをインスタンス変数に保存する場合に使用。
  # 毎回SQLを実行しなくて済むがI18n.reload!しないとDBの値が書き換わっても前回の値が表示される
  # マルチテナント非対応
  # I18n::Backend::ActiveRecord.send(:include, I18n::Backend::Memoize)
  # I18n::Backend::Simple.send(:include, I18n::Backend::Memoize)

  I18n.backend = I18n::Backend::Chain.new(I18n.backend, I18n::Backend::Simple.new)

  # I18n.t()でDBでもファイルでも言語がヒットしなかった場合、その時のkeyやoptions等の情報ををDBに保存したい時に使用
  # 後でレコードやlocaleファイルを追加・更新する時に便利になるが毎度saveが走るためパフォーマンス低下の恐れあり
  # I18n::Backend::Chain.send(:include, I18n::Backend::ActiveRecord::Missing)
  # I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n::Backend::Simple.new)
end

使い方

1. 通常

config/locales/ja.yml

ja:
  user:
    name: ymlのユーザー名
$ bundle exec rails c

[1] pry(main)> I18n.t('user.name')
=> 'ymlのユーザー名'

[2] pry(main)> Translation.create(locale: :ja, key: 'user.name', value: 'DBのユーザー名')
=> #<I18n::Backend::ActiveRecord::Translation...........

[3] pry(main)> I18n.t('user.name')
=> 'DBのユーザー名'

2. proc

$ bundle exec rails c

[1] pry(main)> Translation.create(locale: :ja, key: 'test.proc', value: '1+2', is_proc: true)
=> #<I18n::Backend::ActiveRecord::Translation...........

[2] pry(main)> I18n.t('test.proc')
=> 3

Kernel.eval(value)してるだけみたい。ソース

3. I18n::Backend::ActiveRecord::Missingの使用時

config/initializers/i18n_active_record.rb

# I18n::Backend::Chain.send(:include, I18n::Backend::ActiveRecord::Missing)
# I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n::Backend::Simple.new)

↓コメントアウトを外す

I18n::Backend::Chain.send(:include, I18n::Backend::ActiveRecord::Missing)
I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n::Backend::Simple.new)
$ bundle exec rails c

[1] pry(main)>  I18n.t('user.name', name: 'なまえ', append: 'です')
=> "translation missing: ja.user.name"

[2] pry(main)> Translation.last
=> #<...Translation... id: 1, locale: :ja, key: 'user.name', value: nil, interpolations: [:name, :append], ....

DBに入っていないものを参照したときにレコードが自動的に作られる。
interpolationsカラムにその時の引数の名前が入る。

注意事項

このままではI18n.tを呼ぶたびに毎回DBアクセスが走るのでキャッシュを使用する方法も次回記述します。
次回の記事

【Rails】I18nの言語データをDBから取得 / キャッシュ使用【i18n/i18n-active_record】

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

前回「I18nの言語データをDBから取得」では毎回DBアクセスが走りパフォーマンスに不安があるためキャッシュを使用する方法を記述します。

前回の記事

3.config/initializers/i18n/cacheable.rbの作成

i18nのオープンクラスを使用

module I18n
  module Base
    def translate(*args)
      options  = args.last.is_a?(Hash) ? args.pop.dup : {}
      key      = args.shift
      backend  = config.backend
      locale   = options.delete(:locale) || config.locale
      handling = options.delete(:throw) && :throw || options.delete(:raise) && :raise # TODO: deprecate :raise
      translate_result(key, backend, locale, handling, options)
    end
    alias t translate

    def translate_result(key, backend, locale, handling, options)
      cache_key = translate_cache_key(locale, key, options)
      # キャッシュから取得orキャッシュを作成
      Rails.cache.fetch(cache_key) do
        enforce_available_locales!(locale)
        result = catch(:exception) do
          if key.is_a?(Array)
            key.map { |k| backend.translate(locale, k, options) }
          else
            backend.translate(locale, key, options)
          end
        end
        result.is_a?(MissingTranslation) ? handle_exception(handling, result, locale, key, options) : result
      end
    end

    def translate_cache_key(locale, key, options = {})
      File.join(locale.to_s, key.to_s, options.presence.to_s)
    end
  end
end

3.config/initializers/translation/cacheable.rbの作成

レコードとキャッシュを一緒に作成、更新、削除する

Translation.class_eval do
  after_create :create_i18n_translate_cache
  after_destroy :delete_i18n_translate_cache
  after_update :reset_i18n_translate_cache

  private

  def create_i18n_translate_cache
    I18n.t(key, locale: locale) # 一回呼んでキャッシュ作成
  end

  def delete_i18n_translate_cache
    Rails.cache.delete(delete_cache_key)
  end

  def reset_i18n_translate_cache
    delete_i18n_translate_cache
    create_i18n_translate_cache
  end

  def delete_cache_key
    I18n.translate_cache_key(locale_was, key_was)
  end
end

【jQuery】開閉パネルを最初から開いた状態にする

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Javascriptが苦手なWebデザイナーです。基礎的なことから学んでいる状態なので、簡単なことでもつまずいてしまうという方向けの内容です。

◆Javascript

$(function(){
  $(".toggle").show();
    $(".accordion dt").on("click", function() {
      $(this).next().slideToggle();
      $(this).toggleClass("active");
    });
    $(".accordion dt").mouseover(function(){
      $(this).addClass("over");   
      });
    $(".accordion dt").mouseout(function(){
      $(this).removeClass("over");    
  });
});

◆CSS

.accordion {
    clear: both;
    width: 100%;
    padding: 0;
}
/* dt */
.accordion dt {
    background: url(img/arrow.png) no-repeat 98% 50% #aab6ba;
    background-size: 15px;
    padding: 10px;
    color: #fff;
    cursor: pointer;
    margin: 0;
}
    .accordion dt.active {
        background-image: url(img/arrow.png);
    }
    .accordion dt.over {
        background-color: #c8cfd2;
    }
/* dd */
.accordion dd {
    width: 100%;
    border: 1px solid #aab6ba;
    box-sizing: border-box;
    padding: 10px;
    margin: 0;
}

◆html

<dl class="accordion">
  <dt>開閉スイッチ</dt>
  <dd>
    <ul class="toggle">
      <li>内容</li>
      <li>内容</li>
      <li>内容</li>
    </ul>
  </dd>
</dl>

解説
$(".toggle").show(); で最初は開いている状態にします。
.accordion dt をクリックすると、パネルが開閉するという仕組みになってます。


あとがき
最初から表示させつつ開閉バーをマウスオーバーしたら色が変わって矢印をくるってさせる方法がわからず解決までに時間がかかってしまったので、備忘がてらまとめました。
案件や要望によってコロコロとしようが変わるので、臨機応変に対応していく力が必要です。
Javascriptが苦手なWebデザイナーさんのお役に立てれば嬉しいです。


参考サイト
開閉パネルを最初から開いた状態にする

【超初心者向け】Javascriptの確認ダイアログを複数設置する方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

業務で複数の確認ダイアログを表示させたいことがあり、1つのhtml内に複数設置する方法がわからなかったので備忘します。 検索してもなかなか思った通りの解決方法が見つからず、試行錯誤の上、解決方法を発見しました。

javascript

function sample01() {
    if(window.confirm('サンプル1のコメントです。よろしいですか?')){
    }
}

function sample02() {
    if(window.confirm('サンプル2のコメントです。よろしいですか?')){
    }
}

function sample03() {
    if(window.confirm('サンプル3のコメントです。よろしいですか?')){
    }
}

html

<head>
  <script src="sample.js"></script>
  <script src="jquery.js"></script>
</head>

<body>
  <a onClick="sample01" href="#">サンプル1リンク</a>
  <a onClick="sample02" href="#">サンプル2リンク</a>
  <a onClick="sample03" href="#">サンプル3リンク</a>
</body>

解説
確認ダイアログで表示されるコメントを記述したjavascriptファイルを、html内の <head> ~ </head> 内に記載します。(ここではsample.jsとします。)
javascriptの sample01 とhtmlに記載する onClick="sample01" を同じ名前にすることがポイントです。
たったこれだけで、1つのhtml内に複数の確認ダイアログを設置することが可能です。


あとがき
この方法がもうわからず、数ヶ月後に謎が解けました。
謎が解けてみると簡単ですが、わからない人にはわからないんです。
エンジニアさんはきっとこんなことで悩まないだろうけど、Javascript知識のないデザイナーにはこれだけでも一苦労なんです!

Webデザイナーの方で、Javascriptが得意ではなく、きっと同じような悩みを持った方がいると思うので、参考になればいいなと思います。


参考サイト
確認ダイアログを表示する


検証ブラウザ
Chrome / Firefox / Safari / Edge / IE10
※全て最新版

【レスポンシブ対応】CSSだけで三角矢印の見出しを作る方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

画像を使わずに、CSSだけでレスポンシブに対応した三角矢印の見出しを作る方法をご紹介します。

① 背景を塗りつぶした三角矢印の見出しを作る

サンプル
enter image description here

.title-01 {
    position: relative;
    background: #000;
    color: #fff;
    text-align: center;
    font-size: 24px;
    padding: 40px 0;
    margin: 0;
}
    /* 下三角 */ 
    .title-01:after {
        border: 30px solid transparent;
        border-top-color: #000;
        border-bottom-width: 0;
        bottom: -29px;
        content: "";
        display: block;
        left: 50%;
        position: absolute;
        width: 0;
    }

親となる要素にposition: relative;を付与します。
三角形となる要素にafter擬似要素を追加しposition: absolute;を付与します。

border: 30px solid transparent; の部分で三角形の大きさを調整します。
bottom: -30px; で三角形の位置を調整します。border: 30px solid transparent; よりも大きい数値の場合、三角形の位置が離れます。
left: 50%; はレスポンシブにしても常に中央に表示されます。

親要素にデザインcssを追加・変更できます。
paddingmarginなどは、用途に合わせて追加してください。


② 三角矢印だけのシンプルな見出しを作る

サンプル
enter image description here

.title-02 {
    position: relative;
    color: #000;
    text-align: center;
    font-size: 24px;
    padding: 30px 0;
    margin: 0;
}
    /* 下三角 */ 
    .title-01:after {
        border: 20px solid transparent;
        border-top-color: #000;
        border-bottom-width: 0;
        bottom: 0;
        content: "";
        display: block;
        left: 50%;
        position: absolute;
        width: 0;
    }

①の応用辺です。
親要素を背景色と同じにして、三角矢印だけ残したシンプルなデザインです。

親要素にデザインcssを追加・変更できます。
paddingmarginなどは、用途に合わせて追加してください。


③ 下線と三角矢印の見出しを作る

サンプル
enter image description here

.title-03 {
    position: relative;
    border-bottom: 2px solid #000;
    color: #000;
    text-align: center;
    font-size: 24px;
    padding: 30px 0 10px;
    margin: 0;
}
    /* 下三角 */ 
    .title-01:after {
        border: 25px solid transparent;
        border-top-color: #000;
        border-bottom-width: 0;
        bottom: 0;
        content: "";
        display: block;
        left: 50%;
        position: absolute;
        width: 0;
    }

border-bottom: 2px solid #000; の solid 部分を dotted や dashed にすると、点線や破線が作れます。border-styleの詳細はこちら。

親要素にデザインcssを追加・変更できます。
paddingmarginなどは、用途に合わせて追加してください。


④ 三角矢印の見出しを線だけで作る

サンプル
enter image description here

.title-04 {
    position: relative;
    border-bottom: 2px solid #000;
    background: #fff;
    color: #000;
    text-align: center;
    font-size: 24px;
    padding: 30px 0 10px;
    margin: 0;
}
    /* 下三角 */ 
    .title-04:before{
        content: "";
        position: absolute;
        bottom: -44px;
        left: 50%;
        margin-left: -2px;
        border: 22px solid transparent;
        border-top: 22px solid #fff;
        z-index: 2;
    }
    .title-04:after {
        position: absolute;
        border: 24px solid transparent;
        border-top-color: #000;
        border-bottom-width: 0;
        bottom: -25px;
        content: "";
        left: 50%;
        z-index: 1;
    }

①〜③の応用ですが、こちらでは三角要素にbefore擬似要素を追加します。
親要素のborder-bottom: 2px solid #000;で線の太さや色を指定しています。
before擬似要素のborder:border-top:の数値を同じ値にし、それらの倍数をbottomにマイナス数値で指定、after擬似要素のborder:を「before擬似要素で設定した数値」−「親要素で設定した数値」の値にすると、線の太さが均一になります。
after擬似要素のbottom:はafter擬似要素のborder:から−1を指定していますが、線の太さによって微調整が必要です。

親要素にデザインcssを追加・変更できます。
サンプルでは線の太さを2pxにしてますが、線の太さと色は自由にカスタマイズ可能です。
paddingmarginなどは、用途に合わせて追加してください。


あとがき

Webサイト制作の業務で「見出しにインパクトがない」とよく言われるので、使いやすい三角矢印の見出しを自分のWebデザイン制作の備忘に書きました。
デザインcssのカスタマイズが可能なので、Webデザイナーのみなさまのお役に立てると幸いです。


参考サイト

【CSS】CSSのみで三角と矢印を作る方法
画像を使わず、CSSで吹き出しを作る


検証ブラウザ
Chrome / Firefox / Safari / Edge / IE10
※全て最新版

[GCP] Cloud BuildでGKEのデプロイ by Slack

0

Information

この記事はアピリッツの技術ブログ「あぴらぼ式」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Cloud BuildでGKEのデプロイ

Cloud BuildでGAE/Goデプロイ by Slack の番外編として、Cloud Build を使ってGKE(Google Kubernetes Engine)にデプロイをする設定を実施してみたいと思います。

アプリのコードはこちらです。アプリ自体はGo言語のWebアプリケーションフレームワークGinのQuick Startを少し改変したものです。

[GCP] GAEのエッジキャッシュ利用時の落とし穴

0

Information

この記事はアピリッツの技術ブログ「あぴらぼ式」から移行した記事です。情報が古い可能性がありますのでご注意ください。

TL;DR

GAEのエッジキャッシュを利用する時は課金を有効にしましょう。

Google App Engine

みなさん、Goolge App Engineをお使いでしょうか。

Cloud BuildでGAE/Goデプロイ by Slack vol.4

0

Information

この記事はアピリッツの技術ブログ「あぴらぼ式」から移行した記事です。情報が古い可能性がありますのでご注意ください。

前回 Cloud BuildでGAE/Goデプロイ by Slack vol.3

Cloud BuildでGAE/Goのデプロイ

Cloud BuildでGAE/Goデプロイ by Slack vol.4ということで、
今回はCloud BuildでGAE/Goをデプロイする設定を行います。

といっても、
ここまでの設定ができていれば、
デプロイ自体はgcloudコマンドを使えば、コマンド一発で済むので難しいことはありません。

では、早速やってみましょう。

Cloud BuildでGAE/Goデプロイ by Slack vol.3

0

Information

この記事はアピリッツの技術ブログ「あぴらぼ式」から移行した記事です。情報が古い可能性がありますのでご注意ください。

前回 Cloud BuildでGAE/Goデプロイ by Slack vol.2

Cloud Source RepositoriesのコミットとCloud Buildとの連携

Cloud BuildでGAE/Goデプロイ by Slack vol.3ということで、
今回はCloud Buildをフックする部分について、実施したいと思います。

前回までで、Cloud Source Repositoriesへのマージの連携までできていますので、
このマージをフックしてCloud Build を起動する流れとなります。

Cloud BuildでGAE/Goデプロイ by Slack vol.2

0

前回 Cloud BuildでGAE/Goデプロイ by Slack vol.1

Information

この記事はアピリッツの技術ブログ「あぴらぼ式」から移行した記事です。情報が古い可能性がありますのでご注意ください。

SlackとBitBucketの連携

Cloud BuildでGAE/Goデプロイ by Slack vol.2ということで、
今回はSlackとBitBucketとCloud Source Repositoryを連携する設定を行いたいと思います。
(BitBucketのアカウント、およびリポジトリはすでに存在する前提で話を進めます)

Angular と cordovaでアプリを作ってみる

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

スマホアプリはJavaやObjective-Cなどでごりごり書くのが最もスタンダードな方法ですが、HTMLからアプリを生成してくれるフレームワークを使うハイブリッドアプリと呼ばれる方法もあります。 Angular と Cordova からアプリの機能を提供する機会があったので、まとめます。

開発環境

CordovaとAngular CLIのインストール

npm install @angular/cli --save
npm install cordova --save

npmパッケージをローカルのnode_modules以下にインストールしています。
グローバルを汚してもよい方は -g オプションでどうぞ。

Cordovaプロジェクトの作成

npx cordova create bibioapp

同じフォルダに bibioapp が作成されます。
このままアプリを作成することも可能ですが、今回はAngularのアプリを作成をすすめます。

npx は、ローカルにいれたnpm パッケージのコマンドを実行するコマンドです

Angularプロジェクトで上書きする

はじめに、www 以下とpackage.jsonを待避します

mv bibioapp/www bibioapp/www.bak
mv bibioapp/package.json bibioapp/package.json.bak
npx ng new bibioapp

Angularアプリを起動する

デフォルトで使用するブラウザで開きます。

cd bibioapp
npx ng serve --open
enter image description here

Angularをビルドする設定

Cordovaでビルドできるように angular.json を編集します。
(5から6になって、ファイル名がかわりました。Angular は設定がころころ変わりますね)
outputPath を www に変更します。

      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
             "outputPath": "www",
             "index": "src/index.html",
             "main": "src/main.ts",

ビルドを実行します

npx ng build

www 以下にbundleされたhtml,css,jsが出力されます。

index.htmlを書き換える

src/index.html がビュー側のエントリポイントとなります。
Angularアプリを作成する前にとったバックアップから必要なタグを追加します

変更点を列挙していきます。

Baseタグは.からの相対パスに変更します。

<base href="./">

Content-Security-Policy を追加する

<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">

view port を変更する

<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">

bodyに cordova.js のscriptタグを追加する

<script type="text/javascript" src="cordova.js"></script>

config.xml を編集する

widget要素 の id 属性がパッケージ名になるので、適当に変更する。
今回は com.example.bibioapp にしました。

プラットフォームの追加

Android を追加します。

npx cordova platform add android@6.4.0

なお、パッケージ名を書き換えた場合は、一度削除してから再度追加しましょう。

npx cordova platform remove android

SDKとエミュレータの追加

Android Studioを起動し、アプリルート/platforms/android を開きます。

SDKを追加します。
Tools > SDK Manager を選択し、SDK Platforms タブから Android 8.1(API Level27)を選択します。

その後、エミュレータを追加します。

AVD Managerを起動して、エミュレータを追加します。

Android Studio のメニューバー Toolsから AVD Managerを起動します。

Create Virtual Deviceボタンをクリックし、Nexus 5Xを選択しNextをクリック、Oreo(API Level27)をDownloadしたあとに Nextをクリック、最後に内容を確認したあとに Finishをクリックします。

その後、エミュレータを起動します。

エミュレータで起動する

npx cordova emulate android

ビルドが開始され、しばらくするとアプリが起動します。

enter image description here

Cloud BuildでGAE/Goデプロイ by Slack vol.1

0

Information

この記事はアピリッツの技術ブログ「あぴらぼ式」から移行した記事です。情報が古い可能性がありますのでご注意ください。

自動的にデプロイ

どんなアプリケーションであれ、
世の中に価値を提供するためには、デプロイメントを行う必要があります。

そして、
アプリケーションを一度作ったら終わりということは稀で、
継続的に、かつ頻繁に改修を加えていくことが多いので、
必然的にデプロイも継続的に、かつ頻繁に行うことになります。

いわゆるCI/CDですね。

casperjs のスクリプトを crontab で実行する

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

JavascriptでレンダーされるWebページの特定部分の情報を取ってくるみたいなことをするとき casperjs を使ったスクリプトが便利だけれど、cron実行しようとしたところ思うように動くまでに手こずったのでメモ。

環境

$ uname -mprsv
Darwin 17.7.0 Darwin Kernel Version 17.7.0: Thu Jun 21 22:53:14 PDT 2018; root:xnu-4570.71.2~1/RELEASE_X86_64 x86_64 i386
$ node -v
v10.7.0
$ phantomjs --version
2.1.1
$ casperjs --version
1.1.4
$ python --version
Python 2.7.15

スクリプト

$ cat /Users/kadosawa/bin/doruby

#!/usr/bin/env casperjs

var url = "https://doruby.jp/";
var casper = require('casper').create();

casper.start(url, function() {
  var that = this;
  var title = casper.evaluate(function() {
    return $('#newest-entries div.entry').first().text();
  });
  this.echo(new Date + ' ' + title);
}); //開始

casper.run();

crontab内容

PATH=$PATH:/usr/bin:/usr/local/bin
* * * * * /Users/kadosawa/bin/doruby >> /tmp/doruby.log.txt 2>&1

ポイント
crontab だと node や phantomjs や python やらのパスがなくてエラーになるのでPATH変数を設定してさしあげます。


  • 118 views

自分のファイル名を見て振る舞いを変えるシェルスクリプト

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


長いことsshコマンドの横着方法を検討しておりましたが「これでいいや」と思うことにしました。そこで使った小技を書きます。

linux を覚えたころ bashrc や bash_profile に alias xxx=’ssh -p 65522 -l loginu’ のようなことをしていました。.ssh/config を利用することで scp, rsync のときにオプションが落ちるという課題が解決されましたが、他のマシンに移動させるときや対象を増やすときの手数が少し多いことが課題でした。若干原始的ですが実行ファイルを作成する方法です。

環境

$ uname -mprsv
Darwin 17.7.0 Darwin Kernel Version 17.7.0: Thu Jun 21 22:53:14 PDT 2018; root:xnu-4570.71.2~1/RELEASE_X86_64 x86_64 i386
$ bash --version
GNU bash, version 4.4.12(1)-release (x86_64-apple-darwin16.4.0)
## 省略 ##

基礎:実行すると自身のファイル名を返すスクリプト

#!/bin/bash

basename $0

※ 適当な名前のファイルにして実行権限を与えておきます。

解説
$0 を呼び出すとコマンド名(ファイル名) が返されます。
パスも含まれる為 basename で脱がせます。ファイル名だけになります。

応用:ssh横着に役立てる

~/bin/localhost というパスのファイルを作成しました。

#!/bin/bash

timestamp=`date "+%y%m%d_%H%M%S"`$1
mkdir -p $HOME/sshlog
DST=`basename $0`
logfile="$HOME/sshlog/$USER.`uname -n`_to_$DST.$timestamp.log"
ssh $DST $* | tee $logfile
echo $logfile

所感

  • ln -s ~/bin/localhost ~/bin/サーバー名とすることで1回のコマンドで接続先を増やすことができます。.bashrc を書き換えて、source コマンドを実行してみたいにしなくてよいです。
  • 変数展開を利用すればより複雑なコマンドの実行もできそうです。
  • こういうスクリプトなどを書くことを想定してホストの命名規則やミドルウェアの構成が整理されているとスクリプトに例外用のコードを書く手間が省けます。

googlebotのレンダリングは古い。そして普通のブラウザとちょっと違う。

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Googlebotでjavascriptが読み込める様になってきてはいますが、最新のjavascriptの機能には対応しておらず、chrome41で動いているようです(2018/7ではバージョン67)。そのためブラウザでは正常に表示されていてもgooglebotではエラーになり、javascriptが実行されない状態でキャッシュされてしまう可能性があるので注意です。ちなみにこのレンダリング機能のことをWebレンダリングサービス(WRS)と言うそうです。

chrome41のWRSでサポートされている機能、されていない機能は以下で確認できます。
●chrome41でサポートされている機能
https://www.chromestatus.com/features#milestone%3C%3D41
●chrome41でサポートされていない機能
https://www.chromestatus.com/features#milestone%3E41

個人的な感覚ではIEと同じような対応範囲です。逆にIEにjavascriptが対応していればgooglebotでも動くかなと思います。

また、googlebotはchrome41といってもブラウザの表示と全く同じではなく、

  • WebSQLやService Worker、WebGL
  • は無効 ローカルストレージやCookieはクリアされる
  • 許可が必要なものは許可しない(Notificationsなど)

などの違いがあります。

このようにブラウザの表示と違いがあるため、googlebotがどのようにページを取得しているかちゃんと確認する必要があります。

search consoleの
・Fetch as Google
https://www.google.com/webmasters/tools/googlebot-fetch
・(スマホの場合)モバイルフレンドリーテスト
https://search.google.com/test/mobile-friendly
などで確認でき、エラーがあった場合もエラー内容が返却されるためわかりやすいです。

javascriptで画面を作成した後は、googlebotで正常に動くか確かめた方がよいかもしれません。

AWS + Nginx + UnicornでRailsアプリを公開してみる

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

はじめに

今ならAWSの諸機能が、特定条件下なら1年無料で使えるとのことだったので、試しにRailsアプリをAWS上で作成・公開出来るようにしてみました。

以下のサイトなどを参考にしています。
(デプロイ編①)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで
【AWS】Ruby on Rails + Nginx + Unicorn + MySQL 環境構築

Cloud9で環境を構築する。

Cloud9とは、AWS上で利用できるクラウドIDEです。
AWSコンソールのCloud9から、環境を構築できます。

EC2インスタンスは、t2.microタイプであれば無料枠の範囲で利用できるので、こちらを選択します

構築が終わると、cloud9のコンソールが開きます。

rubyとrailsはインストールされているようなので、今回はこのままアプリを作成します。

$ ruby -v
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]
$ rails -v
Rails 5.2.0

# アプリの作成
$ rails new test-app
$ rails g scaffold user

# マイグレートとアセットプリコンパイル
$ rake db:migrate RAILS_ENV=production
$ rake assets:precompile

Unicornの導入と設定

Gemファイルに追記してUnicornを使えるようにします。

# Gemfile 追記
group :production, :staging do
    gem 'unicorn'
end

# インストール
$ bundle install

config配下に、unicornの設定ファイル(unicorn.rb)を作成・編集します。

  #  unicron.rb
  # set lets
  $worker  = 2
  $timeout = 30
  $app_dir = "/home/ec2-user/environment/test-app/" #アプリの場所
  $listen  = File.expand_path 'tmp/sockets/.unicorn.sock', $app_dir
  $pid     = File.expand_path 'tmp/pids/unicorn.pid', $app_dir
  $std_log = File.expand_path 'log/unicorn.log', $app_dir

  # set config
  worker_processes  $worker
  working_directory $app_dir
  stderr_path $std_log
  stdout_path $std_log
  timeout $timeout
  listen  $listen
  pid $pid

  # loading booster
  preload_app true

  # before starting processes
  before_fork do |server, worker|
    defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
    old_pid = "#{server.config[:pid]}.oldbin"
    if old_pid != server.pid
      begin
        Process.kill "QUIT", File.read(old_pid).to_i
      rescue Errno::ENOENT, Errno::ESRCH
      end
    end
  end

  # after finishing processes
  after_fork do |server, worker|
    defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
  end

Nginxの導入と設定

# Nginxの導入
$ sudo yum install nginx
-- 省略 --
Complete!

# 設定ファイルの書き換え
$ sudo vi /etc/nginx/nginx.conf

pid "/var/run/nginx.pid";
events {
  worker_connections 2048;
}

http {
  upstream unicorn {
    server unix:/home/ec2-user/environment/test-app/tmp/sockets/.unicorn.sock;
  }
  server {
    listen 80;
    server_name XXX.XXX.XXX.XXX; ←EC2インスタンスに割り当てられたIP
    root /home/ec2-user/environment/test-app/;
    error_log /home/ec2-user/environment/test-app/log/nginx.log;
    include /etc/nginx/mime.types;
    location / {
      if (-f $request_filename) { break; }
      proxy_set_header X-Real-IP  $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_pass http://unicorn;
    }
  }
}

unicornとnginxの起動

NginxとUnicornを起動して、webページが閲覧出来るか確認してみます。

 # unicornの起動
$ bundle exec unicorn_rails -E production -c config/unicorn.rb -D
 # 起動確認
$ ps aux | grep unicorn

#nginxの起動
$ sudo service nginx start
#起動確認
$ ps aux | grep nginx

起動後、EC2インスタンスのIPアドレスにアクセスしたところ無事繋がりました。
(なにもない簡素なページですが。。。)

終わりに

AWSを利用して、railsで作成したアプリをweb公開できました。
NginxやUnicornについて理解がまだ浅いので、どんな設定が出来るのかなど理解を深めていきたいと思います。

【Rails】巨大なテーブル同士をjoinせずに検索【速度改善】

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

巨大なテーブル同士をjoinしてから検索すると遅くなるのでjoinせずに検索する方法を記述します。

例として下記のようなテーブル関連とします。

Post ー* TagPost ー* Tag
 |
 *
Comment

# 投稿
class Post < ActiveRecord::Base
  has_many :comments
  has_many :post_tags
  has_many :tags, though: :post_tags
end

# 中間テーブル
class PostTag< ActiveRecord::Base
  belongs_to :post
  belongs_to :tag
end

# タグ
class Tag < ActiveRecord::Base
  has_many :post_tags
  has_many :posts, though: :post_tags
end

# コメント
class Comment < ActiveRecord::Base
  belongs_to :post
end

上記の状態でコメントとタグのタイトルに「あ」という文字が入っている投稿を取得したい場合はテーブルをjoinして検索すると思います。

Post.joins(:comments, :tags).where(['comments.title LIKE ? AND tags.title LIKE ?', '%あ%', '%あ%' ])

ですががレコード数がそれぞれ数十万件以上だった場合とてもjoinしていられません。かなり遅くなるかと思います。そこで

それぞれのテーブルでpost_idを取得してそれをもとにPostを取得する

# コメントのpost_id取得
comment_post_ids = Comment.where(['title LIKE ?',  '%あ%']).pluck(:post_id)

# タグのid取得
tag_ids = Tag.where(['title LIKE ?',  '%あ%']).pluck(:id)

# タグのpost_id取得
tag_post_ids = PostTag.where(tag_id: tag_ids).pluck(:post_ids)

# 取得したpost_idが一致しているものを取得
post_ids = comment_post_ids & tag_post_ids

# 投稿を検索!
posts = Post.where(id: post_ids)

ポイント

  • pluckを使う
  • 取得したidたちで「&アンド」(どちらかに入っていればいい場合「|オア」)を取る

SQLを複数回実行しますが巨大なテーブル同士をjoinするよりは早くなることがあります。

ActiveRecordのwhereの挙動メモ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

ActiveRecordのwhereの挙動が同じだったり違ったりするのでメモ

例として使うテーブル

# 投稿
class Post < ActiveRecord::Base
  has_many :comments
end


# コメント
class Comment < ActiveRecord::Base
  belongs_to :post
end

1.whereにhash

Post.where(title: 'タイトル').to_sql
SELECT posts.* FROM posts WHERE posts.name = 'タイトル'  ORDER BY posts.id ASC

default_scopeがつく

2.whereにArray

Post.where(['title = ?', 'タイトル']).to_sql
SELECT posts.* FROM posts WHERE (name = 'タイトル')  ORDER BY posts.id ASC

whereの条件にテーブル名がつかない。()がつく。

3.Arrayの部分にテーブル名を入れる

Post.where(['posts.title = ?', 'タイトル']).to_sql
SELECT posts.* FROM posts WHERE (posts.name = 'タイトル')  ORDER BY posts.id ASC

テーブル名がつく。()がつく。

4.whereに空配列

Post.where([]).to_sql
SELECT posts.* FROM posts ORDER BY posts.id ASC

where条件なし。全件取得。default_scopeがつく。

5.whereに空配列

Post.where([[]]).to_sql
SELECT posts.* FROM posts WHERE () ORDER BY posts.id ASC

全件取得。where ()がつく。

6.whereにString

Post.where("posts.title = 'タイトル'").to_sql
SELECT posts.* FROM posts WHERE (posts.name = 'タイトル')  ORDER BY posts.id ASC

Arrayのときとかわらない。

7.whereに空文字

Post.where('').to_sql
SELECT posts.* FROM posts  ORDER BY posts.id ASC

where条件なし。全件取得。default_scopeがつく。

8.whereにtrue

Post.where(true).to_sql
RuntimeError: unsupported: TrueClass

例外。

9.whereに’true’

Post.where('true').to_sql
SELECT posts.* FROM posts WHERE (true)  ORDER BY posts.id ASC

全件取得。

10.whereに’false’

Post.where('false').to_sql
SELECT posts.* FROM posts WHERE (false)  ORDER BY posts.id ASC

0件。

11.joinしてwhereにhash

Post.joins(:comments).where(title: 'タイトル', comments: {title: 'コメントのタイトル'}).to_sql
SELECT posts.* FROM posts INNER JOIN comments ON comments.color_id = posts.id WHERE posts.title = 'タイトル' AND comments.title = 'コメントのタイトル'  ORDER BY posts.id ASC

Postのdefault_scopeがつく。

12.joinしてmerge

Post.joins(:comments).where(title: 'タイトル').merge(Comment.where(title: 'コメントのタイトル')).to_sql
SELECT posts.* FROM posts INNER JOIN comments ON comments.color_id = posts.id WHERE posts.title = 'タイトル' AND comments.title = 'コメントのタイトル'  ORDER BY posts.id ASC, comments.id ASC

PostとCommentのdefault_scopeつく。

[AWS] LambdaでOpenCVを使用

0

Information

この記事はアピリッツの技術ブログ「あぴらぼ式」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Lambda on PythonでOpenCVライブラリを使う

AWS S3(以下、S3)に画像ファイルをアップロードした際、
AWS Lambda(以下、Lambda)で画像加工を行う、というのは
よく使われるケースの一つかと思います。

そこで、Lambda on Python 2.7でOpenCVライブラリを使用するための手順について、ご紹介したいと思います。

ライブラリのimport

[AWS] Fargateの使用上の注意点

0

Information

この記事はアピリッツの技術ブログ「あぴらぼ式」から移行した記事です。情報が古い可能性がありますのでご注意ください。

AWS Fargateって?

AWS Fargate(以下Fargate)は、
AWSが提供するコンテナ実行サービスであるElastic Container Service (以下ECS)のサービスの一種です。

バージニア北部のリージョンでのみ提供されていたサービスですが、
ついに、2018年07月東京リージョンでも提供が開始されました!!

既存のECSの仕組みが、ユーザが管理するEC2のクラスタの上でコンテナが起動されるのに対し、
FargateはEC2の管理をする必要がなく、コンテナが使用するvCPU、メモリを指定するだけでコンテナを実行できます。

冒頭でECSのサービスの一種です、という言い方をしましたが、
基本的には、ECSの仕組みと同じように動作します。

おすすめのAfterEffects無料エフェクトプラグイン紹介

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

セイバープラグイン、ライトセイバーのようなエフェクト他パチンコとかによくあるオーラ系の演出で使われるエフェクトが簡単に作れます
https://www.flashbackj.com/video_copilot/saber/

Color Vibrance、真っ白や真っ黒な画像でも色相や彩度を自在に補正かけることができます。
https://www.flashbackj.com/video_copilot/free_plugin/

サンプルとしてカグヅチさんに燃えていただきました
enter image description here

ざっくりですが手順としましては
1AfterEffectsにエフェクトつけたい画像を読み込む
2レイヤー→オートトレースでキャラとかエフェクトをつけたい物の型のパスを取る
3オートトレースしたレイヤーにエフェクトからセイバーを選択。今回はカグヅチなので火をベースにするためPresetはInfernoを元に適当に数値いじります(この辺は個人差あるので適当にいじってもらった方が楽しいかもです)
Customize Coreの項目にあるCore typeをLayer Maskにするとエフェクトがトレースしたパスに沿ってオーラをまとった感じになります

そのままだとリアルなエフェクトになるのでキャラの雰囲気に合わせて
ポスタリゼーション、ブラー(詳細)、カートゥーンのエフェクトを入れていい感じに調整したら
VC Color Vibranceで好みの色味に調整します。

これは別にサンプルなんで適当にざっくりやっちゃってますがもう少し細かく数値設定してあげればもう少し面白く仕上がるかなと思います。

ちなみにセイバープラグインはAfterEffectsの最新バージョンだと対応していないため要注意です

最近人気な記事