俺でもできるもんな

独立系SI企業から完全異業種のベンチャー企業に転職、社内のITインフラを整えるべく颯爽と登場した自称天才プログラマー俺のハートフルブログ

Redmine プラグイン 今更ながらEasyガントチャートを導入してみた

はじめに

Easyガントチャートとは

ガントチャートを直感的にいじることができるプラグインです。
https://www.easyredmine.com/redmine-gantt-plugin
今回は無料版を導入しました。

導入の経緯

プロジェクトを管理していたらリスケすることって多々あるじゃないですか。
その度にチケットの開始日と期限をいちいち更新するのって結構手間ですよね。
親チケレベルでリスケしようとしたら10個とか20個とかのチケットの開始日と期限を変えないといけないわけです。
もっと手軽に開始日と期限を更新したい!と思ってこのプラグインの導入を決めました。

導入手順

プラグインファイルを取得する

こちらから無料版のプラグインをダウンロードします。
https://www.easyredmine.com/redmine-gantt-plugin スクリーンショット 2017-09-08 11.48.51.png

Redmineプロジェクトに配置

ダウンロードしたzipをredmine/htdocs/pluginsに展開します。

bundle install

いつものようにpluginsに配置して再起動したらエラーとなったので調べた結果、
bundle installが必要なようです。
easy_ganttに移動してbundle installをしましよう。

db:migrate

bundle installして一安心し、再起動したらまたエラーとなったので調べた結果、
db:migrateも必要なようです。
rake --trace db:migrate RAILS_ENV=productionしましょう。

再起動

最後に再起動して完了です。
Redmine上の 管理>プラグイン で確認しましょう。

設定

各プロジェクトでEasyガントを有効にする

設定>モジュール でEasyガントを有効にします。 スクリーンショット 2017-09-08 11.55.54.png 有効にしたら、プロジェクトメニューにEasyガントチャートが追加されます。

実際のプロジェクトデータを取り込む

Easyガントチャートに移動すると、サンプルデータが表示されていると思うので(初回だけ)、
実際のプロジェクトデータを取り込むボタンを押して実際のプロジェクトデータを取り込む。

動作確認

こんな感じに移動できます。 タイトルなし.gif

惜しいところ

  • 期間の拡張はできない(横に広げれない)
  • おそらくデフォルトのテーマにしかデザインの完全な対応はしていない

Rails Stripe サブスクリプション決済実装 初期設定をしてAPIを使える状態にする

概要

Stripeでのサブスクリプション決済実装をRailsで行う場合、
公式で提供されているgemを使用することになると思います。

実装に当たって
Stripe::Plan.create()
Stripe::Customer.create()
のようなAPIメソッドを使用していくことになるのですが、
今回はAPIを使える状態にするまでの初期設定についてまとめました。

事前準備

いつもの

Gemfileに gem 'stripe'
を追加して
bundle install
しておきましょう。

確認

rails cでStripeメソッドが使えるか試しておきましょう。
Stripe::Customer.listは登録されている顧客の情報リストを取得するメソッドです。

irb(main):001:0> Stripe::Customer.list
Stripe::AuthenticationError: No API key provided. Set your API key using "Stripe.api_key = <API-KEY>". You can generate API keys from the Stripe web interface. See https://stripe.com/api for details, or email support@stripe.com if you have any questions.

当たり前ですが、エラーとなります。

APIを使用するのに必要なアカウント情報

必要な情報は

  • Publishable key
  • Secret key

といった2つのkeyです。

Stripe管理画面の以下の箇所より取得できます。(色々白抜きしてます) スクリーンショット 2017-09-06 17.30.17.png

開発フェーズの場合、Test用のkeyを使用するようにしましょう。

設定記述

stripe-rubyのREADMEにはこう書かれています。
https://github.com/stripe/stripe-ruby#usage

require "stripe"
Stripe.api_key = "sk_test_..."

# list charges
Stripe::Charge.list()

# retrieve single charge
Stripe::Charge.retrieve(
  "ch_18atAXCdGbJFKhCuBAa4532Z",
)

もちろんこれでもAPIは使用できます。
しかし、必要な箇所で毎回

require "stripe"
Stripe.api_key = "sk_test_..."

と書くのは効率がいいとは言えませんし、セキュリティ的にもアウトです。

なので、今回は以下の2つのファイルにkey情報を記述します。

  • config/secrets.yml
  • config/initializers/stripe.rb

secrets.ymlについては以下の記事を参照してください。
Rails 5.1のencrypted secretsの運用について考える

config/secrets.yml

stripe_publishable_keyとstripe_secret_keyを定義します。
環境に合わせてdevelopment、test、productionは切り替えてください。

development:
  # stripe
  stripe_publishable_key: pk_test_********************
  stripe_secret_key: sk_test_********************

config/initializers/stripe.rb

デプロイ時にStripeの定義を読み込みます。

Rails.configuration.stripe = {
  publishable_key: Rails.application.secrets.stripe_publishable_key,
  secret_key: Rails.application.secrets.stripe_secret_key
}

Stripe.api_key = Rails.application.secrets.stripe_secret_key

準備完了

以上でAPIを使用する準備は完了となります。
簡単ですね!!

確認

先ほどと同じメソッドを使って確認します。
(サーバー再起動してくださいね)

irb(main):001:0> Stripe::Customer.list
=> #<Stripe::ListObject:*****> JSON: {
  "object": "list",
  "data": [....],
  "has_more": true,
  "url": "/v1/customers"
}

正常なレスポンスが返ってきました。
(Customerがemptyの場合は見え方が違うかも…)

参考

EC2 SGのインバウンド・アウトバウンドに説明の項目が追加されてるー

IP見ただけでどこのIPかなんて把握できるか

これはうちのシステムのあるSGのインバウンドルールです。
IPは白塗りしています。 c63fe2e4-b30f-1d38-8198-4b93e85a4bf5.png

昨日までは説明の項目はなく画像の通りでした。
SSHを6IPから許容していますが、一体これがどこのIP誰のIPかさっぱりわかりませんでした。
オフィスのIPが変わったときもどのIPと入れ替えたらいいかわからず、さらに追加する始末です。

説明の項目ができたので説明を記述できる

6e890515-bff9-74af-56eb-6a5f12da1c84.png

これによって無駄なルールを削除したり、
変更の際に一発でわかるようになったりします。

遅すぎる改良

まあでも文句言っても仕方ないんです。 Amazonサンキュー:v:

注意

現在以下の文字しか使えないらしい。
256 characters from the following set: a-zA-Z0-9. _-:/()#,@[]+=&;{}!$* プレースホルダーの例に日本語入ってるのに!!!

Rails Ransack sort_linkが使えない統計カラムなどをソートするヘルパーを作ってみた

事実確認とやりたいこと

Ransackのsort_linkでは統計カラムのソートができない

Railsプロジェクトにおいて検索機能を「Ransack」というgemを使って作成している場合、
sort_link()というヘルパー一発でソート機能を実装できます。
しかし、それは単にModelに存在しているカラムのソートが簡単に実装できるヘルパーであってSUMなどの統計後のデータに対してのソートはできません。

例えば以下のような売上データがあるとします。

salesテーブル

id name price
1 うまい棒 10
2 うまい棒 10
3 よっちゃんイカ 30
4 うまい棒 10
5 うまい棒 10

このテーブルをSUMで統計して売上合計が大きい順にソートしたいです。
期待している出力結果は以下の通りです

name price
うまい棒 40
よっちゃんイカ 30

しかし、sort_link()ではModelに存在しているカラムしか指定できません。
sort_link(@q, :price)では以下のような出力となってしまいます。

name price
よっちゃんイカ 30
うまい棒 40

やりたいこと

sort_link(@q, :total_price)みたいなのができたらベストだと考えます。
ぐぬぬぬ。何かいい方法はないのでしょうか?

ソートするヘルパーを作ってしまえ

「ないのなら作ってしまおう。今後も使うことあると思うし!」
と勢いで作ってみました。
JSまで巻き込んでしまったのは自分でもいい判断だったのかはわからないですが、
こんな感じに実装しました。

Controller

orderでsortパラメーターを使ってソートします。

@q = Sales.select('name, sum(price) as total_price').group(:name).order(params[:sort]).ransack(search_params)
@sales = @q.result

View

テーブルのヘッダーに今回作ったヘルパーtable_sort()を指定します。
検索ありです。
※slimを使っています。

= search_form_for @q, url: sales_path, class: 'search-form' do |f|
  = hidden_field_tag :sort
  = f.search_field :name_cont,
  = f.submit '検索'


table
  thead
    tr
      th = "name"
      th = table_sort('price', 'total_price')
    - @sales.each do |item|
      tr
        th = item.name
        th = item.total_price

Helper

ヘッダーに表示するテキストとソートする対象の名前を引数に、
href="javascript:void(0)"のlink_toを返します。

# テーブルのソートリンクを作成する
def table_sort(text, target)
  order = (params[:sort].present? && params[:sort].include?(target) && params[:sort].include?('asc')) ? 'desc' : 'asc'
  text +=  params[:sort].present? && params[:sort].include?(target) ? params[:sort].include?('asc') ? '' : '' : ''
  link_to text, 'javascript:void(0)', class: 'sort-link', data: {colmun: target, order: order}
end

Javascript

今回JSを使用したのは検索条件を引き継ぐためです。
リンクの最後にgetパラメータを全て連ねる方法もありますがスマートじゃないと思いやめました。

$(function() {
    $(document).on("click", ".sort-link", function() {
      $('#sort').val($(this).data('colmun') + ' ' + $(this).data('order'));
      $('.search-form').submit();
    });
});

最後に

ベストプラクティスなのかはわかりませんが、今のところ自分では満足しています。
イイね!と思ったら使ってみてください。

Rails migration decimalカラムをデフォルトで作成すると小数点以下が0桁になるから気をつけよう

decimalをデフォルトで作成すると小数点以下が入力できない

例えば重さを保存するカラムを作る場合はmigrationファイルにこんな感じで書きますよね?

class CreateHoges < ActiveRecord::Migration[5.1]
  def change
    create_table :hoges do |t|
      t.decimal :weight
    end
  end
end

しかし、設定値なしでdecimalカラムを作成する場合

`weight` decimal(10,0) DEFAULT NULL

で作成されてしまうんです。

面倒臭がらずに許容桁数を指定しましょう

桁数の指定optionは以下の通りです。

option value
precision 全体の桁数
scale 小数点以下の桁数

以下のように書いた場合は全体で6桁、小数点以下2桁です。

class CreateHoges < ActiveRecord::Migration[5.1]
  def change
    create_table :hoges do |t|
      t.decimal :weight, precision: 6, scale: 2
    end
  end
end

注意点

  • precisionは全体の桁数です。
  • precisionは整数の桁数ではないです。

Redmine チケットの文中に画像プレビューを載せる裏技

Redmineのチケットに画像プレビューをつけたい時ってありますよね?

Redmineで「こんな感じにお願い!」、「ここ変になってるよ!」などを伝える際に実際のスクリーンショットや写真があったほうが断然わかりやすいのは言うまでもありません。
↓イメージ↓ スクリーンショット 2017-07-29 15.03.22.png

しかし、RedmineにはQiitaみたいに画像プレビューを「ぽんっ」と表示する機能はありません。
※あるかもしれませんが知りません

Redmineチケット上での画像の扱い

ここで画像をアップすると スクリーンショット 2017-07-29 14.39.27.png こんな感じにアップされますね スクリーンショット 2017-07-29 14.42.49.png

チケット内容の説明のために必要な画像だとしたら、
「ここがおかしいので修正よろー(添付画像参照)」
といったように本文を書くことになると思います。

しかし、Redmineのチケット上のファイルアップロード機能はこういう用途ではないのでしょう。
「追加資料です!」とか、「添付画像をファビコンとして使用してください!」とかそういうのに使うんだと思います。

チケット本文中に画像を載せるならURLを指定すればいい

URL指定で画像を載せることができます。 スクリーンショット 2017-07-29 14.51.52.png しかしローカルにある画像ファイルにグローバルなURLなんて存在しません。
なので、先ほどチケットに添付した画像のURLを指定します。 スクリーンショット 2017-07-29 14.52.34.png プレビューはいい感じですね。
しかし添付画像がダサいとても。

つまりグローバルな画像URLが簡単に作れればいい

ここに行き着くと思います。
リモートストレージに設置してそのURLを….ってめんどくさいわ!!!
ということで画像のURLを作る裏技を紹介します。

Qiitaを使う方法

ここに画像をアップします。 スクリーンショット 2017-07-29 15.01.41.png グローバルなURLが作成されます。 スクリーンショット 2017-07-29 15.02.23.png

Githubを使う方法

ここに画像をアップします。 スクリーンショット 2017-07-29 15.05.47.png グローバルなURLが作成されます。 スクリーンショット 2017-07-29 15.06.03.png

作成したURLをRedmineで使う

Qiita or Githubで作成したグローバルのURLを使います。 スクリーンショット 2017-07-29 15.10.30.png プレビューはこんな感じになります。 スクリーンショット 2017-07-29 15.03.22.png

担当者に優しい説明になりましたね^^

注意

  • 今回のQiita、Githubの使い方は両サービスにとって正しい使い方ではありません。
  • くれぐれも自己責任でお願いいたします。
  • QiitaのフローはQiita:Teamで行うと外部サイトから閲覧できない画像になるのでお気をつけて。
  • Githubの無料枠には100MBの制限があります。

Rails 多言語化対応 Model編

はじめに

今後のサービス化していくシステムは多言語化対応が必須となってきます。
なので、多言語化の方針と記述方法を簡単にまとめたので目を通してください。
View編を先に一読ください↓
Rails 多言語化対応 View編

参考サイト

以下のサイトを参考にしました。
記事を読む前に一読お願いします。
モデル名やモデルの属性名の多言語化

実装

dictionary

1つのファイルに全文言をかくと意味不明状態になるので、
参考サイトに倣って然るべき場所に然るべきファイルを作成し文言を記述していきます。
今回はbrandのvalidationで使いたかったので

  • config/locales/models/brands/ja.yml
  • config/locales/models/brands/en.yml

を作成しています。

ja:
  activerecord:
    models:
      brand: ブランド
    attributes:
      brand:
        id: ブランドID
        name: ブランド名
        name_en: ブランド名(英語)
        sellable_jp: Sellable JP
        sellable_us: Sellable US
        brand_category_id: ブランドカテゴリー
en:
  activerecord:
    models:
      brand: Brand
    attributes:
      brand:
        id: Brand ID
        name: Brand Name
        name_en: Brand Name(English)
        sellable_jp: Sellable JP
        sellable_us: Sellable US
        brand_category_id: Brand Category

これ以外にも階層を持った書き方もできたりします。
詳しくは調べてください。

結果

locale = :jaの場合
スクリーンショット 2017-07-27 21.45.16.png

locale = :enの場合
スクリーンショット 2017-07-27 21.45.29.png

補足

「を入力してください」の部分はvalidatesを使えば自動で変換されます。