紙一重の積み重ね

アラフォーのエンジニアがなれる最高の自分を目指して、学んだことをこつこつ情報発信するブログです。

【クラウドIDE】Cloud9が無料で使えなくなってしまったのでGitpodを試してみた話

はじめに

場所に限らず、ネットにさえ繋がっていれば、どこからでもコードが書けるCloudIDEは、AtCoderの学習や、ちょっとしたコードを書きたいときにとても便利です。

私はRailsチュートリアルをきっかけに、Cloud9で個人的な開発を進めてきました。無料で使えたため重宝していました・・・が、AWSに買収され、6月末をもって私のワークスペースが削除されてしまいました。AWS本家のCloud9にしようか迷いましたが、1年間の無料枠があるとは言え、EC2インスタンス料金がかかってしまうため、無料で使えるCloudIDEを探すことにしました。

代替案

  • coder
    • VSCodeが使える、という情報をQiitaで得たのですが、登録方法がよくわかりませんでした。 coder.com
  • Gitpod
    • 今回はこちらを採用することにしました。 www.gitpod.io

Gitpod設定手順

  • Githubにログインする
  • https://www.gitpod.io/ にアクセスして、右上の Go to app をクリック image
  • 自分のGithubアカウントと連携する
  • チェックを入れて、 Create free acount をクリックする image
  • ワークスペースの雛形が表示される。
    • Railsdjangoの雛形も選べる模様。
      • ここから先、どうしていいかちょっと迷う。 image
  • 上記のワークスペース作成では特に何もせず、自分のGithubリポジトリのURLの先頭にgitpod.io/#を付与してアクセスする
  • しばらくすると、VSCodeっぽい画面と、Welcomeダイアログが表示される image
  • 自分のGithubリポジトリの内容が、VSCodeで表示される
    • うおおおお!ブラウザでVSCodeが動いてる!!!感動!!!
    • 以下のキャプチャは私のAtCoder学習用リポジトリです image

Gitpodを触ってみる

コンソールによるファイル作成

  • ディレクトリ移動はもちろん、touchコマンドなど、問題なく動きました。 image
  • irbも問題なく動きました。 image

rubyを書いてみる

  • getsと入力しただけで、to_iが補正されました。 image

Gitへのadd,commit,push

  • こちらも問題なくできました image
  • pushすると、なぜか失敗しました。
$ git push
remote: Invalid username or password.
  • どうやら認証するための権限が無いようです。画面上部にエラーダイアログが表示されます。
    • Grant Permissions をクリックします。 image
  • Githubの認証画面が表示されるので、Authorize gitpod-ioをクリック image
  • Gitpodに返ってくるので、OKをクリック image
  • 再度、git pushを実行
    • 今度は無事にpushできました!
$ git push
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 16 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 444 bytes | 222.00 KiB/s, done.
Total 4 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/yokoyan/atcoder_problems.git
   8ad5c48..cad4d30  master -> master

まとめ

ということで、今回はCloud9の代わりにGitpodを試してみました。Cloud9でできていたことが、Gitpodでも問題なくできることが確認できたので、AtCoderのコードを書く環境はGitpodを採用したいと思います!!

【Devise】ユーザのメール認証が成功した際に、管理者向けにメール送信処理を組み込む方法 #ruby #Rails

f:id:yokoyantech:20190319153636p:plain

はじめに

最近、Deviseをいじる機会があったのでメモ。

やりたいこと

  • Deviseのメール認証に成功した後に、管理者向けに「ユーザがメール認証したよ」的なメールを送信したい
    • send_user_confirmed_emailみたいな感じ

困ったこと

素直に実装すると、ユーザがURLをクリックするたびに管理者にメールが飛んでしまう。

実現方法1

resource.errors.empty?で認証エラーがなければ、管理者にメール送信。

class Users::ConfirmationsController < Devise::ConfirmationsController
  def show
    # 略
    super
    Users::Mailer.send_user_confirmed_email.deliver! if resource.errors.empty?
    # 略
  end
end

実現方法2(こっちのほうがよりスマート)

認証成功後に特定の処理を実行するには、after_confirmationを使用する。

github.com

Userモデル内でオーバーライドすればOK。

class User < ApplicationRecord
  devise :database_authenticatable, :recoverable, :registerable, :confirmable,
         :trackable, :lockable, :validatable, :timeoutable, authentication_keys: [:login]
  # 略
  def after_confirmation
    Users::Mailer.send_user_confirmed_email.deliver!
  end
end

【Ruby2.6.0】find_spec_for_exe: can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException) エラーの解決方法

f:id:yokoyantech:20190111165620p:plain

はじめに

新年早々ハマったのでメモ。 今年の1月から同様の事象が発生しているように見受けられます。

stackoverflow.com

結論

Ruby2.6.0を使えば解決します。

やりたいこと

  • まっさらなEC2にRubyを入れて、Unicornをインストールしたい

実行環境

$ ruby --version
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
$ which bundler
/home/ubuntu/.rbenv/shims/bundler

発生したエラー

  • CodeDeployがいつまで経っても失敗するなと思ったら、Unicornの起動に失敗していた。
$ sudo systemctl status unicorn
● unicorn.service - Staging Unicorn Server
   Loaded: loaded (/lib/systemd/system/unicorn.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Fri 2019-01-11 11:40:00 JST; 7min ago
  Process: 4574 ExecStart=/home/ubuntu/.rbenv/shims/bundle exec unicorn_rails -c /home/ubuntu/hoge/config/unicorn.rb -E staging (code=exited, status=1/FAILURE)
 Main PID: 4574 (code=exited, status=1/FAILURE)

Jan 11 11:40:00 ip-10-2-3-58 systemd[1]: Started Staging Unicorn Server.
Jan 11 11:40:00 ip-10-2-3-58 unicorn[4574]: /home/ubuntu/.rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:289:in `find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)
Jan 11 11:40:00 ip-10-2-3-58 unicorn[4574]:         from /home/ubuntu/.rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:308:in `activate_bin_path'
Jan 11 11:40:00 ip-10-2-3-58 unicorn[4574]:         from /home/ubuntu/.rbenv/versions/2.5.1/bin/bundle:23:in `<main>'

原因

Gemfile.lockに記載されているBUNDLE_WITHのバージョンと、bundlerのバージョンが異なるため。

Gemfile.lock

RUBY VERSION
   ruby 2.5.1p57

BUNDLED WITH
   1.17.1

bundlerのバージョン確認

$ bundler -v
Bundler version 2.0.1
$ gem list
*** LOCAL GEMS ***
bigdecimal (default: 1.3.4)
bundler (2.0.1)

根本的な原因

bundler2のバグ。

bundler.io

対処方法

案1 bundlerのバージョンを下げる

ググるとだいたいこの方法がヒットする。 詳細は以下のサイト参照。

blog.hokkai7go.jp

qiita.com

案2 Ruby2.6.0を使う

Bundlerが標準で組み込まれたため、Ruby2.6.0を使用する。 自分のプロダクトの今後を考えるとこっちのほうが良さそう、ということでこっちを採用。

Bundler を Default gems として標準添付しました。

www.ruby-lang.org

【Rails5】axlsx_railsを使ってCSV出力機能を実装する

f:id:yokoyantech:20190109155303p:plain

はじめに

axlsx_railsを使ってCSV出力機能を実装するメモ。

やりたいこと

  • Rails5アプリケーションからCSVを出力したい

実現方法

実装方法

gemインストール

gem 'axlsx_rails'

MIMEの登録

長いので\config\initializers\mime_types.rbに登録する。

Mime::Type.unregister :xlsx
Mime::Type.register 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', :xlsx

実装

View

  • Excelのヘッダー部とデータ部を定義する。
  • app/view/hoge/fuga.xlsx.axlsxという感じで作成する。
wb = xlsx_package.workbook

wb.styles do |s|
  row_style = s.add_style alignment: { horizontal: :left, vertical: :top, wrap_text: true }
  wb.add_worksheet(name: "source") do |sheet|
    # ヘッダー
    headers = [t('activerecord.attributes.user.user_code'),
               t('activerecord.attributes.user.user_name')]
    sheet.add_row headers, style: row_style

    # データ
    @hoge.each do |hoge|
      row = [hoge.user.user_code, hoge.user.user_name]
      sheet.add_row row, style: row_style
    end
  end
end

Controller

  • respond_toメソッドの呼び出し
    • xlsxのフォーマットでリクエストが来た場合、app/view/hoge/fuga.xlsx.axlsxを表示する。
    • templateには、上部で定義したExcelのフォーマットの場所を指定する
def csv
  respond_to do |format|
    format.html
    format.xlsx do
      response.headers['Content-Disposition'] = 'attachment'
    end
  end
  render xlsx: source_file_name, template: 'hoge/fuga'
end

参考情報

qiita.com

【Rails5】Punditを使って権限管理の機能を実現する

f:id:yokoyantech:20190108135720p:plain

はじめに

Punditを使った権限管理の実装方法のメモ。

やりたいこと

権限管理の機能を簡単に実装したい。

実現方法

Punditを使う。

github.com

実装

application_controller

  • Punditをインクルードする
class ApplicationController < ActionController::Base
  include Pundit

application全体のpolicy

  • policyクラスをapp/policies/に配置する
  • ApplicationPolicyで基本的なpolicyを定義する
class ApplicationPolicy
  attr_reader :user, :record

  def initialize(user, record)
    @user = user
    @record = record
  end

  def index?
    user.accessible?(record)
  end

  ・・・

end

Model独自のpolicyを定義する

  • ApplicationPolicyを継承する
  • recordはモデルオブジェクトが入る
class HogePolicy < ApplicationPolicy
  def edit?
    record.fuga_flg && user.accessible?(record) || user.hoge_admin?
  end
end

controllerの実装

  • before_actionで権限チェックすると便利
  • authorizeメソッドは、引数に渡した@hogeから対応するHogePolicyを確認して、current_userrecordを返す
class HogeController < ApplicationController
  before_action :authorize_user

  def authorize_user
    set_hoge if params[:id]
    authorize @hoge
  end
end

末尾にイコールがついているメソッドは代入構文として使える #Ruby

f:id:yokoyantech:20181214180034p:plain

はじめに

たまにメソッドにイコールがついているものを見かけるのでメモ。

実装例

def user_params=(user)
  id = user.id
  self.created_user ||= id
  self.updated_user = id
end

メリット

代入構文のように使用できる

Rubyでは、()を省略できる。また、イコールの前後に空白があっても無視されるため、user_params = userと書くと、user_params=メソッドが呼び出される。

参考情報

ja.stackoverflow.com

teratail.com

まとめ

初見だとわかりませんでした。Rubyはこういう書き方もできるのが面白いですね。

【Rails5 + Slim】ブラウザのメニューバーやツールバーなどを表示せずに、リンクを新しいウインドウで開く方法

f:id:yokoyantech:20181029174950p:plain

やりたいこと

  • リンクを別のウインドウで表示したい
  • 別のウインドウには、ブラウザのツールバーやメニューを表示したくない
  • 別ウインドウの大きさは手動で調整できるようにしたい

やりたいことのイメージ

  • 楽天銀行のログイン画面のこういうやつ f:id:yokoyantech:20181121140138p:plain

www.rakuten-bank.co.jp

実行環境

  • Rails5.2
  • Slim

実現方法

link_to @hoge.id, edit_hoge_path(@hoge), onclick: "window.open(this.href, 'hoge', 'height=800, width=1200'); return false;"

'height=800, width=1200'のオプション部分を指定することで、menubarなどのオプションの初期設定値は全て非表示にできる。 最後のreturn false;を外すと、親画面も遷移してしまうので注意。

参考情報

uxmilk.jp