ホーム ブログ ページ 42

devise ログイン後のリダイレクトについて(POST編)

0

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

Rails の Devise でログイン後にログインする直前のPOSTリクエストにリダイレクトさせます。

 目標

RailsでPOSTリクエストではリダイレクトできないため、deviserログイン後はGETリクエストのみリダイレクトできます。

下記の場合、お気に入り登録が出来ないし、お気に入り一覧にリダイレクトできないです。

未ログイン⇒商品詳細⇒お気に入り登録(POST)⇒ログイン画面⇒ログインする⇒お気に入り一覧

 対策

POSTなので、直接遷移が出来なくて、after_login_to_postを作成して、その後自動サブミットすれば、POSTリクエストにリダイレクトを実現します。

動き:

未ログイン⇒商品詳細⇒お気に入り登録(POST)⇒ログイン画面⇒ログインする⇒after_login_to_post⇒真っ白ページ(自動サブミット)⇒お気に入り一覧

 セッションに POST リクエストのパラメータを保存

POSTリクエスト中で、POSTリクエストのパラメータ、コントローラ、アクションをセッションに保存します。

class CustomersFavoritesController < ApplicationController
  before_action :authenticate_customer!, except: :create
  def create
    if current_customer.signed_in?
      current_customer.favorites.create(product_id: params[:id]) unless current_customer.favorites.find_by(product_id: params[:id])
      redirect_to action: :index
    else
      #セッションに POST リクエストのパラメータを保存
      session[:after_login_to_post] = {
        controller_name: controller_name,
        action_name: action_name,
        params: { id: params[:id] }
      }
      redirect_to new_customer_session_path
    end
  end
end

 ログイン後のリダイレクトをカスタマイズ

ログイン後、セッションにPOST情報があれば、after_login_to_post_pathにリダイレクトさせます。

class CustomersSessionsController < Devise::SessionsController
  # ログイン後、リダイレクト先メッソドafter_sign_in_path_forをオーバーライドする。
  def after_sign_in_path_for(resource)
   #お気に入り登録(POST)の場合、after_login_to_post_pathに遷移します。
    if session[:after_login_to_post]
      after_login_to_post_path
    else
      super
    end
  end
end

 ログイン後にセッション情報からログイン直前のページ情報を復元

セッション情報から、POSTリクエストの情報を取得し、設定します。

class TopController < ApplicationController
  def after_login_to_post
   #セッションにafter_login_to_postがあれば、
    if session[:after_login_to_post]
      @back_controller = session[:after_login_to_post]['controller_name']
      @back_action = session[:after_login_to_post]['action_name']
      @params = session[:after_login_to_post]['params']
   #セッションをクリア
      session[:after_login_to_post] = nil
      render :after_login_to_post, layout: false
    else
      #直接アクセスが来たら、TOPに遷移する。
      redirect_to top_path
    end
  end
end

 真っ白VIEW

after_login_to_postのVIEWは自動サブミットします。

一瞬だけ真っ白なページが表示されますが、

自動サブミットによって、POST送信が出来ます。

after_login_to_post.slim

doctype transitional
html[xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja" dir="ltr"]
  head
    meta[http-equiv="Content-Type" content="text/html; charset=UTF-8"]
    title = '戻る'
  body onLoad="document.forms[0].submit()"
    - if @back_controller && @back_action && @params
      = form_tag( { controller: @back_controller, action: @back_action }, { method: 'post' } ) do
        = hidden_field_tag 'id', @params['id']
        <noscript>
        = button_tag '戻る', class: 'btn_sub'
        </noscript>

 routes

  ### ログイン後、POSTアクションに戻る ###
  get 'after_login_to_post', to: 'top#after_login_to_post'

 参照

http://easyramble.com/cannot-post-redirect-on-rails.html

devise ログイン後のリダイレクトについて(GET編)

0

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

Rails の Devise でログイン後はログインする直前のGETリクエストにリダイレクトさせます。

 デフォルトの動き

before_action :authenticate_user!を通して、ログイン画面に遷移する場合、ログイン後、ログイン直前の画面に戻します。

下記のようなredirect_toを利用して、ログイン画面に遷移する場合、ログイン後、元の画面に戻らなくて、root_pathに遷移します。

unless user_signed_in?

redirect_to new_user_session_path

 対策

ログイン直前のリクエストをセッションに保存しておいて、

ログイン成功後のafter_sign_in_path_forメソッドをオーバーライドして、戻る先をセッションから取得して設定します。

注意:ログイン関連のリクエストをセッションに入れないこと。

 ログイン直前のリクエストをセッションに保存

applictaion_controller.rb

class ApplicationController < ActionController::Base
  after_action  :store_location
  def store_location
    if (request.fullpath != "/users/sign_in" &&
        request.fullpath != "/users/sign_up" &&
        request.fullpath !~ Regexp.new("\\A/users/password.*\\z") &&
        !request.xhr?) # don't store ajax calls
      session[:previous_url] = request.fullpath 
    end
end

 deviseのリダイレクをカスタマイズ

devise標準のafter_sign_in_path_forをオーバーライドして、ログイン後のリダイレクト先はカスタマイズします。

SessionsControllerをカスタマイズしなければ、applictaion_controller.rbに追加します。

SessionsControllerをカスタマイズすれば、カスタマイズしたコントローラ中に追加します。

class UsersSessionsController < Devise::SessionsController
  ・・・
  def after_sign_in_path_for(resource)
    if (session[:previous_url] == root_path)
      super
    else
      session[:previous_url] || root_path
    end
  end
end

 参照

https://github.com/plataformatec/devise/wiki/How-To:-Redirect-back-to-current-page-after-sign-in,-sign-out,-sign-up,-update

http://easyramble.com/friendly-forwarding-redirect-on-devise.html

Rails 4.2 にアップデートすると他のマシンからサーバーにアクセスできなくなる?

0

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

一瞬ハマったのでメモとして書き残します。

 Rails 4.2 にアップデートすると他のマシンからサーバーにアクセスできなくなる?

「rails s」で起動するサーバーの IP アドレスはもともとは「0.0.0.0」でしたが、

Rails 4.2 から「localhost」になっているようです。

この影響で他のマシンや、ホスト OS から立ち上げたサーバーにアクセスできない!

ということがあります。

 解決方法

いままで通りにアクセスできるようにするには簡単で、「rails s -b 0.0.0.0」のような

オプションを指定するだけです。オプションの詳細は「rails –help」で確認できます。

rails s
#=> 'http://localhost:3000' で起動するため外部からアクセス不可
rails s -b 0.0.0.0
#=> 'http://0.0.0.0:3000' となり、いままで通りアクセス可能

 どこで変わったの?

Rails のサーバー部分の実装に使われている Rack に、デフォルト IP の変更があったみたいです。単純に「その方が安全だよね」という話ですね。

参考: https://github.com/rack/rack/commit/28b014484a8ac0bbb388e7eaeeef159598ec64fc

Railsの可逆暗号化方法 ActiveSupport::MessageEncryptorの使用方法

0

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

Railsで簡単に可逆暗号化方法を提供しています。ActiveSupport::MessageEncryptorです。

今日は、ActiveSupport::MessageEncryptorの使い方についてご紹介します。


①プレーンテキスト(message)、鍵(secret)を以下のようにする。
2.1.1 :001 > message = ‘test’
 => “test”
2.1.1 :002 > secret = SecureRandom::hex(50)
 => “06e40eedc81374bbef74bb2ac1c4a5d9928287c5146949d8d56a566495a5c8ecb8499177bce629d55a8e485d7dc66a183d47”
2.1.1 :003 >

②ecryptorの宣言(AES-256, Cipher Block Chainingで暗号化)
2.1.1 :003 > encryptor = ::ActiveSupport::MessageEncryptor.new(secret, cipher: ‘aes-256-cbc’)
 => #, @serializer=Marshal>

③暗号化(encrypt_and_sign)
2.1.1 :006 > encrypt_message = encryptor.encrypt_and_sign(message)
 => “YjBvd0dOemF5YWN3eHI1OXRUUmk5Zz09LS11OXR6akNlK0IxWUFTdyt5YTlQUWNBPT0=–737d367a2db323c2890084a3139e1e39e7e16c5d”

④復号化(decrypt_and_verify)
2.1.1 :007 > encryptor.decrypt_and_verify(encrypt_message)
 => “test”

以上は、通常の使い方です。

でも、ここで、注意しないとできないのは、
③暗号化(encrypt_and_sign)
2.1.1 :006 > encrypt_message = encryptor.encrypt_and_sign(message)
は、実行するたびに、結果が変わります。
2.1.1 :012 >   encrypt_message = encryptor.encrypt_and_sign(message)
 => “bjZOekxmZnlqRUtzT3V4NFBNb2lqdz09LS1FVEFVZ0xsTUFRK2U2dWZtUmRQZ0RBPT0=–8f8882f9d87d60d7ac85069cd7d2d58d105bbf25”
2.1.1 :013 > encrypt_message = encryptor.encrypt_and_sign(message)
 => “am1sQzI5SUhweG43TFVrK05hb3lPdz09LS1Cb0d3SHZKa2dobjQxU3ZLWVRpd3B3PT0=–b951c5800a881b79d309cace046349b41866936b”

ソースを見れば、原因がわかると思いますが、
.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/message_encryptor.rb

 67
 68     def _encrypt(value)
 69       cipher = new_cipher
 70       cipher.encrypt
 71       cipher.key = @secret
 72
 73       # Rely on OpenSSL for the initialization vector
 74       iv = cipher.random_iv #### => ここです。ivが実行するたびにランダムで生成する
 75
 76       encrypted_data = cipher.update(@serializer.dump(value))
 77       encrypted_data << cipher.final
 78
 79       “#{::Base64.strict_encode64 encrypted_data}–#{::Base64.strict_encode64 iv}”
 80     end
 81

こうすると、暗号化の結果を別のところで、使いたい場合、ivを固定させるカスタマイズする必要があります。

例えば:

 44     def initialize(secret, *signature_key_or_options)
 45       options = signature_key_or_options.extract_options!
 46       sign_secret = signature_key_or_options.first
 47       @secret = secret
 48       @sign_secret = sign_secret
 49       @cipher = options[:cipher] || ‘aes-256-cbc’
 50       @verifier = MessageVerifier.new(@sign_secret || @secret, :serializer => NullSerializer)
 51       @serializer = options[:serializer] || Marshal
 52       @iv = options[:iv]

53     end

 68
 69     def _encrypt(value)
 70       cipher = new_cipher
 71       cipher.encrypt
 72       cipher.key = @secret
 73
 74       # Rely on OpenSSL for the initialization vector
 75       iv = @iv || cipher.random_iv
 76
 77       encrypted_data = cipher.update(@serializer.dump(value))
 78       encrypted_data << cipher.final
 79
 80       “#{::Base64.strict_encode64 encrypted_data}–#{::Base64.strict_encode64 iv}”
 81     end

こうすると、実行するたびに結果が同じです。


irb: warn: can’t alias context from irb_context.
2.1.1 :009 > message = ‘test’
 => “test”
2.1.1 :010 >
2.1.1 :011 > message.encoding
 => #
2.1.1 :012 >
2.1.1 :013 >   secret = SecureRandom::hex(50)
 => “b9aa9c2b5af0349c3b334ead4f8b1e2a3ff42921425bf2df1aefd3d3aefd4b4b5ce816e38fdcad231b985dee8dbf40200d06”
2.1.1 :014 > iv = SecureRandom::hex(20)
 => “fa4ad72743b789ff188c7c50a56b3b563e1e68e9”
2.1.1 :015 > encryptor = ::ActiveSupport::MessageEncryptor.new(secret, cipher: ‘aes-256-cbc’, iv: iv)
 => #, @serializer=Marshal, @iv=”fa4ad72743b789ff188c7c50a56b3b563e1e68e9″>
2.1.1 :016 > encrypt_message = encryptor.encrypt_and_sign(message)
 => “b0NGSXRYQVY2OCs4OS8vcDcrYU12Zz09LS1abUUwWVdRM01qYzBNMkkzT0RsbVpqRTRPR00zWXpVd1lUVTJZak5pTlRZelpURmxOamhsT1E9PQ==–c249ada02f27b5482b682537180c751e266bd608”
2.1.1 :017 >
2.1.1 :018 >   encrypt_message = encryptor.encrypt_and_sign(message)
 => “b0NGSXRYQVY2OCs4OS8vcDcrYU12Zz09LS1abUUwWVdRM01qYzBNMkkzT0RsbVpqRTRPR00zWXpVd1lUVTJZak5pTlRZelpURmxOamhsT1E9PQ==–c249ada02f27b5482b682537180c751e266bd608”
2.1.1 :019 >
2.1.1 :020 >   encrypt_message = encryptor.encrypt_and_sign(message)
 => “b0NGSXRYQVY2OCs4OS8vcDcrYU12Zz09LS1abUUwWVdRM01qYzBNMkkzT0RsbVpqRTRPR00zWXpVd1lUVTJZak5pTlRZelpURmxOamhsT1E9PQ==–c249ada02f27b5482b682537180c751e266bd608”
2.1.1 :021 >


もう一つ、目で見るとき、同じ”test”で、encodingが違うと、暗号化の結果が変わります。


2.1.1 :023 > message.encoding
 => #
2.1.1 :024 > encrypt_message = encryptor.encrypt_and_sign(message)
 => “b0NGSXRYQVY2OCs4OS8vcDcrYU12Zz09LS1abUUwWVdRM01qYzBNMkkzT0RsbVpqRTRPR00zWXpVd1lUVTJZak5pTlRZelpURmxOamhsT1E9PQ==–c249ada02f27b5482b682537180c751e266bd608”
2.1.1 :025 >
2.1.1 :026 > message_sjis = message.force_encode_utf8_to_sjis
2.1.1 :028 > message_sjis.encoding
 => #
2.1.1 :031 > message_sjis == message
 => true
2.1.1 :033 > encrypt_message_sjis = encryptor.encrypt_and_sign(message_sjis)
 => “NkRsUTVWU0M5N3Z4Sm1VUGI3czNsY3poYnRyVGJhdHB3NE5IeE1qMGdQaz0tLVptRTBZV1EzTWpjME0ySTNPRGxtWmpFNE9HTTNZelV3WVRVMllqTmlOVFl6WlRGbE5qaGxPUT09–daf7901c7949383921e3b1b47dc389defd40892d”
2.1.1 :036 > encrypt_message_sjis == encrypt_message
 => false

プロジェクトにRubocopを導入することのメリットとデメリット

0

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

Ruby でコーディングルールを設けるのに役立つ gem「Rubocop」をチームで利用するメリットとデメリットについて紹介します。

 はじめに

チームでプログラミングをするときに立ちはだかる壁のひとつに「コードの統一」があると思います。

どんなに有能な人が複雑な機能を瞬く間に作り上げたとしても、チームで開発し保守する以上は、それが他人に理解できるものでなければあまり意味がありません。

なぜならばたったひとりしか理解できないコードは、その人にしか保守できないからです。

この「コードの統一」を図るために出てくるのがコーディングルールかと思います。

コーディングルールがあれば、皆が理解できるコードを共有し合うことができます。

が、このルールを作るのも守るのも面倒くさい!

そこで導入を検討したのが Rubocop です。

この gem は Ruby のコードを静的に評価して「ここはこう書いた方が良いよ」というアドバイスをくれるというものです。

「これがあればコーディングルールなしにキレイなコードを担保できるかも?!」という希望をもとに、新しいプロジェクトで実際に使ってみることにしました。

この記事では、Rubocop をチームで運用してみて感じたメリットとデメリットを紹介したいと思います。

 Rubocopとは

Rubocop 自体の説明は割愛します。

どんなものかをご存知でない方は下記記事などをご参照ください。

Rubocopを使ってコーディングルールへの準拠チェックを自動化

http://qiita.com/yaotti/items/4f69a145a22f9c8f8333

 Rubocopの運用方法

今回のプロジェクトでは Rubocop を自動テストの一端として組み込む形で利用しました。

この自動テストと GitLab のマージリクエスト (GitHub でいうプルリクエスト) を組み合わせることで

「テストが成功するまでマージできませーん」という流れができるので、 [45/1090]

Rubocop によるコーディングルールを守らざるを得ない環境を作ることができます。

ただし、Rubocop のデフォルト設定はチームで運用するには敷居が高い内容となっているので最初にある程度縛りを緩くしておき、

また途中からでもメンバーからの意見が多ければ設定を変更する体制を取りました。

 Rubocopのメリット

ようやく本題になります。

メリットとしては今回挙げるのは下記の3つになります。

1. コーディングスタイルをある程度統一できる

長いメソッド/モジュールの分割をほぼ強制されるので、

数百行のメソッドや数千行のモジュールがプロジェクト内に生まれることがありませんでした。

2. Ruby 歴が短い人、改善意識の高い人の良い矯正になる

Rubocop が提案してくる内容を素直に受け止められる人は、Rubocop 色に染まることで、

どんどん怒られにくいコードを自発的に書く方向に矯正できているように感じました。

メソッドひとつひとつがシンプルになったり、早い時期からメソッド郡のモジュール化を考えたりするようになったり、と良い感じです。

3. Ruby の新しい構文、便利な構文を知る良い機会になる

Rubocop を使っていると「こういう風に書きたいならこう書いた方が分かりやすいよ」という提案を受けることがあります。

これによっていままで知らなかったメソッドや慣習などを学ぶ機会を得ることができました。

 Rubocopのデメリット

Rubocop 単体のデメリット、というよりも、チームで使う際の注意点というような観点になります。

メリットと同じく、こちらも3つ挙げています。

1. コーディングスタイルをある程度しか統一できない

「メソッドが長いなら分ければ良いんでしょ」と安易に考え、

「method1」「method2」「method3」…のように無意味な名前でメソッドを分割するケースがありました。

残念ながらいま現在の Rubocop はそれを良しとして通してしまうため、

ただ単にメソッド1つの長さが短いだけの、本質的に意味のないメソッド分割を許容してしまうことがあります。

この辺は、「なぜ Rubocop を使うのか」についてチームで共通認識を持っておくべきだと感じました。

2. Ruby 歴が長い人、改善意識の低い人の阻害となる

Rubocop の提案を良しとしない人(たとえば手続き的な記述で書いた方が、

それでメソッドが長くなったとしても分かりやすいと考える人、など)とは、当然衝突することになります。

これは本人にとってもストレスですし、嫌々で書いたコードが良いものになるとも思えません。

ただしこれはどんなコーディングルールにも共通することなのかなと思います。

基本的にはルールを尊重しつつ、どうしてもという場合にはルールを見直していくしかないと思います。

3. 急いでいるときなどに本質的でない指摘で開発が止まる

Aさん「急ぎでこの処理を追加して欲しいんだけど」

Bさん「1行追加するだけでできました!」

Rubocop「メソッドが長いのでエラーです」

Aさん「・・・」

Bさん「・・・」

ということが何度かありました(あと1行だけでも追加すれば Rubocop に怒られる、という罠が巧妙に仕込んである)。

こうなってしまえばリファクタリングを余儀なくされることになるので、後のことを考えれば良いことなのですが、その場では大きなストレスになります。

 さいごに

Rubocop は自分ひとりで利用するのであれば本当に良い味方になると思います。

とくに最近のバージョンはABCメトリクス値の計測も取り入れられて、よりいっそう養成ギブスとしての能力を増しています。

あと、僕個人としては Rubocop が大好きなので心の中でもっと広まれ!と思っています(もっと広まれ!)。

ただしチームやプロジェクトで利用するには使い方に工夫が必要だと感じました。

チームメンバーにコーディングルールの意識をしっかりと共有しておくことである程度は回避可能だと思いますが、もっと良い方法があればぜひ教えてください!

Mac で 暗号化zip を作成する

0

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

ローカル環境で圧縮を行うときは gzip や tar zcf を使うことが多いが

社外の人にファイルを渡すときに暗号化zipを使う。

Windowsでは定番の圧縮解凍ツールに暗号化zipの作成機能があるが

Macは暗号化zip作成ソフトの話は聞かない。

というのもMacで暗号化zipを作成するのに特別なツールをインストールする必要はない。

ターミナルの zip コマンドにオプションをつけるだけで暗号化zipは作成できる。

簡単な操作だが、オプションやファイル名指定の順番をよく忘れてしまい再度検索して試すということが何度かあったので備忘の為に記載する。

単体のファイルを暗号化zipする場合

zip -e target_file.zip target_file.ext

ディレクトリを暗号化zipにする場合

zip -e -r target_directory.zip ./target_directory
-eオプションについて

※ man zip の出力の一部

--encrypt
       Encrypt the contents of the zip archive using a password which is entered on the terminal in response to
       a prompt (this will not be echoed; if standard error is not a tty, zip will exit with  an  error).   The
       password prompt is repeated to save the user from typing errors.

意訳的なもの

--暗号化
     (コマンドの)応答でターミナル上から入力するパスワードを使ってのzipアーカイブ内容の暗号化。
     (このパスワードは画面出力されない;もし標準エラーがttyでなければ、zip(コマンド)はエラー終了する) 
      このパスワード入力は打ち間違いを防ぐ為に再度行う。

仕事で使うScala入門

0

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

プログラミング言語Scalaは、昨今注目が集まっている「関数型プログラミング」を実際のプロジェクトで実践するのに適した有力なプラットフォームです。本エントリではScalaの概要について紹介します。

Scalaとは

スイス連邦工科大学のMartin Odersky教授によって開発されたプログラミング言語です。
Scala(スカラ)という名前は、言語設計の理念であるスケーラブル(Scalable)という言葉からとられています。

特徴について箇条書きでいくつか挙げると

  • JVM(Java仮想マシン)で動作し、Javaで書かれたライブラリやクラスを利用することができる
  • 静的型付け+型推論を行いJVM用のclassファイルにコンパイルされる
  • オブジェクト指向と関数型プログラミングの双方をサポートする(マルチパラダイム)
  • Java8で導入されたラムダ式などの高度な機能をを簡潔な文法で使うことができる

などが挙げられます。

文法は、基本的にJavaやC++などのスタンダードな文法をベースにしていますが、OCamlやHaskellなどの関数型言語に近い簡潔な記述ができるように工夫がこらされています。
弊社で主に使われているRubyにも若干似ているため、親しみが持てるひともいるかもしれません。

本家Webサイト
http://www.scala-lang.org/

Scalaの開発体制

Odersky教授によって開発が始まったScalaですが、現在では教授らが設立したTypesafe社を中心に、 オープンソースソフトウェアとして精力的に開発が続けられています。
https://github.com/scala/scala

開発環境の構築

JDK 1.6以上がインストールされたPCであれば、すぐにインストールして動かすことができます。
http://www.scala-lang.org/download/

また、Macを使っていれば、Homebrewで簡単にインストールすることができます。

しかしなんといってもおすすめは、ScalaをサポートしたIDEをインストールして、その中で開発することです。

IntelliJ IDEAを使いましょう。フルスペックのUltimate Editionは有償ですが、軽量版のCommunity Editionが無料で使えます。
https://www.jetbrains.com/idea/

現在Emacs, Vimを使っているひとは、設定やプラグインによってキーバインドを合わせることができるので問題ありません。私はIdeaVimというVim互換のキーバインドを実現するプラグインを使っています。

長年Eclipseを使っていてもどうしても手放せない、というひとは Scala IDE for Eclipseというプラグインを入れるとScalaが使えるようになるみたいですよ。
http://scala-ide.org/

最初の一歩

お約束として、Hello Worldを書いてみましょう。Scalaのコードはいろいろな方法で実行することができます。

  • コンパイルなしでスクリプトとして実行する
  • REPL(Read Eval Print Loop)の対話環境で実行する
  • .classファイルにコンパイルしてJVMで直接実行する

お仕事で使う場合も、対話環境でいろいろ試しながらコンパイル用のソースコードを書き進めるやり方が便利です。

対話環境でHello World

コマンドラインから scalaコマンドで対話環境を起動します。 scala> という文字列がプロンプトです。


% scala
Welcome to Scala version 2.11.5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_71).
Type in expressions to have them evaluated.
Type :help for more information.

scala> println("Hello World!")
Hello World!

scala> _

println()というのが画面に文字列を出力するメソッドです。正式には Console.println() ですが、デフォルトでimportされているため直接使うことができます。

スクリプトでHello World

拡張子 .scala のファイルにコードを書き、 scalaコマンドで実行します。


% cat hello.scala
println("Hello World!")
% scala hello.scala
Hello World!

ソースコードに書いたメソッドがそのまま実行されるので、Rubyなどのスクリプト言語とほぼ同じように書くことができます。

コンパイルしてHello World


% cat HelloWorld.scala
object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello World!")
  }
}
% scalac HelloWorld.scala
% ls
HelloWorld$.class	HelloWorld.class	HelloWorld.scala
% scala HelloWorld
Hello World!

これで、ソースコードを書き、コンパイルしてからそれを実行することができました。

Javaでは public static void main(String args[]) というシグニチャのメソッドを含むクラスを定義しますが、 Scalaのクラスにはstaticメソッド(Rubyでいうクラスメソッド)というものが存在せず、同じようなことをするためにはクラス(class)ではなくオブジェクト(object)というものを定義します。
Scalaで定義されたobjectも、コンパイルするとJVM用のクラスファイル(拡張子が.class)にコンパイルされます。
用語が紛らわしいですね。でもすぐに慣れます。

おわりに

Scalaという言語がどういうものなのか、その概要を駆け足で説明しました。
インストールも実行も簡単ですので、是非ためしてみて下さい。

Mac homebrew の imagemagick のバージョンを下げる

0

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

大人の事情(保守の関係など)でどうしても古いバージョンのミドルウェアを使用しなければならないことがある。自分が遭遇したのは imagemagick のバージョンを下げなければならないということだった。これはそのメモ。

とあるアプリケーションを動かす為に枯れた ruby をインストール し

gem もさらにバージョンを下げておいた。

 [kadosaway@imac ~]$ ruby -v
ruby 1.9.3p551 (2014-11-13 revision 48406) [x86_64-darwin13.4.0]
[kadosaway@imac ~]$ gem -v
1.7.2
bundle install を実行しようとするとエラーが発生し必要な gem が整えられなかった。
This installation of RMagick was configured with ImageMagick 6.8 but ImageMagick 6.9.0-3 is in use. (RuntimeError)

どうも versions というツールでバージョンを管理できるらしいが

インストールされていなかったのでリポジトリを追加。

[kadosaway@imac ~]$ brew tap homebrew/boneyard
Cloning into '/usr/local/Library/Taps/homebrew/homebrew-boneyard'...
remote: Counting objects: 717, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 717 (delta 0), reused 1 (delta 0)
Receiving objects: 100% (717/717), 172.84 KiB | 196.00 KiB/s, done.
Resolving deltas: 100% (336/336), done.
Checking connectivity... done.
Tapped 66 formulae

そして imagemagick のバージョンリストを取得

[kadosaway@imac ~]$ brew versions imagemagick
Warning: brew-versions is unsupported and will be removed soon.
You should use the homebrew-versions tap instead:
  https://github.com/Homebrew/homebrew-versions

6.9.0-3  git checkout 8b2b988 /usr/local/Library/Formula/imagemagick.rb
6.8.9-8  git checkout 9efbcda /usr/local/Library/Formula/imagemagick.rb
...
そしてフォーミュラ置き場へ移動し、目的のバージョンを再インストールする。
[kadosaway@imac ~]$ cd /usr/local/
[kadosaway@imac local]$ git checkout 9efbcda /usr/local/Library/Formula/imagemagick.rb
[kadosaway@imac local]$ brew reinstall imagemagick
==> Reinstalling imagemagick
==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/imagemagick
Already downloaded: /Library/Caches/Homebrew/imagemagick-6.8.9-8.mavericks.bottle.tar.gz
==> Pouring imagemagick-6.8.9-8.mavericks.bottle.tar.gz

with_optionsでifを用いる時の注意

0

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

社会人1年目真っ最中の中西です。

今回は、model内でwith_optionsを用いた時の、ifの扱いについて紹介します。

環境

Rails 4.1.4

Ruby 2.1.2

with_optionsのif

model内で、バリデーションを書く時に、特定の場合のみバリデーションを動かしたい場合、ifを用います。

validates :test_id, length: { minimum: 50 }, if: test?

def test?
  return false if hogehuga == 'hogehuga'
  true
end

特定の場合のバリデーションが、1つの場合上記で問題ありません。

しかし、特定の場合のバリデーションが複数ある場合、それそれにifをつけるのは大変です。

そこで使用するのが、with_optionsになります。

with_options if: :test? do |v|
  v.validates :test_id, length: { minimum: 50 }
  v.validates :hoge, presence: true
end

with_optionsに条件を付けることにより、バリデーションをグルーピングすることができます。

この時に、with_optionsでまとめたバリデーションの1つに、さらに条件を加えたくなった場合、下記のように書きました。

with_options if: :test? do |v|
  v.validates :test_id, length: { minimum: 50 }
  v.validates :hoge, presence: true, if: :hoge
end

これで、大丈夫だと思っていたら、with_optionsでまとめたバリデーションを行う条件が、

「if: :test?」ではなく「if: :hoge」になっていました。

どうも、with_optionsの条件がifの場合、その中でさらにifを用いるとグルーピングの条件であるifを上書きしてしまうようです。

 解決方法

解決方法は簡単で、with_optionsの条件がifの場合は、その中ではifは使わない様にするだけです。

中でif文を使いたい場合は、逆のunlessを使います。

unlessを使えば、with_optionsのifを上書きすることはありません。

with_options if: :test? do |v|
  v.validates :test_id, length: { minimum: 50 }
  v.validates :hoge, presence: true, unless: 'hoge.blank?'
end

また、with_optionsの条件がunlessの場合には、その中でunlessは使わずに、ifを用いると条件を上書きせずにすみます。

rails4.2のwith_options

上記問題とは全く関係ありませんが、rails4.2では、with_optionsの書き方が少し簡略化されたようです。

 rails4.1

with_options if: :test? do |v|
  v.validates :test_id, length: { minimum: 50 }
  v.validates :hoge, presence: true
end

 raile4.2

with_options if: :test? do
  validates :test_id, length: { minimum: 50 }
  validates :hoge, presence: true
end

ブロック引数をつけなければいけなかったのが、つけなくて良くなったようです。

https://github.com/rails/rails/pull/16339

地味に楽になる気がします。

【Ruby】Railsを使用せずにRubyのCGIをRailsっぽくする【CGI/Apache】

0

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

「一部のページを動的に表示したいけどRailsを入れる程の規模ではない」というような場合に使える方法です。 普通のhtmlと共存できます。 ディレクトリは下記のような場合を想定しています。

http.confの修正

RubyのCGIが使えるようにhttp.confを変更します。 ここでは詳しくは書きません。

1.htaccessを作成

$ cd ドキュメントルート
$ vim .htaccess
=============
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/$ [OR]
RewriteCond %{REQUEST_URI} ^/news/$ [OR]
  ・
  ・    CGI表示したいページを[OR]でつなげて記述していく
  ・
RewriteCond %{REQUEST_URI} ^/news/pickup/$
RewriteRule .* /routes.rb [L]
=============

2.routes.rbの作成

$ which ruby
---rubyのディレクトリ---          ←メモ
$ vim routes.rb
=============
#!---rubyのディレクトリ---

begin
  require './model/application'
  require './controller/application_controller'
  LOAD_DIR = %w(model controller)
  LOAD_DIR.each do |dir|
    Dir.glob("./#{dir}/*.rb").each do |file|
      require file
    end
  end

  # コントローラ生成
  controller_name = Application.get_controller_and_action_name[:controller]
  action_name = Application.get_controller_and_action_name[:action] || 'index'
  @controller = Kernel.const_get([controller_name, '_controller'].join.split('_').map(&:capitalize).join).new

  # アクション呼び出し
  eval "@controller.#{action_name}”

  # view呼び出し
  @controller.render

rescue Exception
  # 例外発生時404 Not Found

  puts 'Status: 404 Not Found\n'
  puts 'Content-Type: text/html\n\n'
  puts ''
  puts '404 Not Found'
  puts "ページは移動または削除されました。"
  puts "トップページへ”

  # エラーログに書き込み
  $stderr.puts "#{$!} (#{$!.class})"
  $stderr.puts $@.join("\n")
end
=============

3. model view controlle のディレクトリ作成

$ mkdir model
$ mkdir view
$ mkdir controller
$ vim model/.htaccess
=============
Deny from all
=============
$ cp model/.htaccess controller
$ cp model/.htaccess view

4. Application モデルの作成

$ vim model/application.rb
=============
class Application
  ROOT_CONTROLLER = :top
  DEFAULT_ACTION = :index

  class << self
    def get_controller_and_action_name
      url_split = ENV['REQUEST_URI'].split('/').delete_if{|element| element.empty? || element.match(/\?/) != nil}
      controller = url_split.first || ROOT_CONTROLLER
      action = url_split[1] || DEFAULT_ACTION
      {controller: controller, action: action}
    end
  end
end
=============

5. Application コントローラの作成

$ vim controller/application_controller.rb
=============
require 'erb'
require "cgi"
require "cgi/session"

class ApplicationController
  attr_accessor :cgi, :session, :params, :controller, :action

  def initialize
    @cgi = CGI.new
    @params = @cgi.params
    @session = CGI::Session.new(@cgi)
    @render_once = true
    params_parse
    @controller = Application.get_controller_and_action_name[:controller]
    @action = Application.get_controller_and_action_name[:action]
  end

  def params_parse
    if @params != nil
      form_array = @params.map do |key, value|
        if value.size == 1 && value.kind_of?(Array)
          

[key.to_sym, value.first]

else

[key.to_sym, value]

end end.flatten(1) end @params = Hash[*form_array] end def redirect_to(url, status=”REDIRECT”) print @cgi.header( { “status” => status, “Location” => url }) end def render(viewfile=nil) if @render_once viewfile ||= “view/#{@controller}/#{@action}.html.erb” @cgi.out(){ ERB.new(File.read(viewfile).force_encoding(“utf-8”)).result(binding) } @render_once = false end end end =============

6. CGIで表示したいコンテンツのviewの作成(ここではTOPページ)

$ mkdir view/top 
$ vim view/top/index.html.erb
==============
  ・
  ・
  ・
<%= @access %> 回目のアクセスです
  ・
  ・
  ・
==============

7. CGIで表示したいコンテンツのmodelの作成(ここではTOPページ)

$ vim model/top.rb
==============
class Top
  SESSION_KEY_ID = ’top'
end
==============

8. CGIで表示したいコンテンツのcontrollerの作成(ここではTOPページ)

$ vim controller/top_controller.rb
==============
require 'csv'
require "time"

class TopController < ApplicationController
  def index
    init_session
    @access = @session[Top::SESSION_KEY_ID][:access]
  end

  private

  def init_session
    @session[Top::SESSION_KEY_ID] ||= {}
    @session[Top::SESSION_KEY_ID][:access] ||= {}
  end
end
==============

これでTOPページヘアクセスするたびにと「XX 回目のアクセスです」がカウントされていくと思います。
動的なページを増やしたいのあれば.htaccessに「/controller/action/」の形式で追記してviewmodelcontrollerを作成するだけで増やせます。

super の話

0

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

こんにちは、bibioです。ruby には super というオーバーライドしているメソッドを呼び出す機能があります。

何気なく使うとはまることがあるので違いを区別します。

説明した通り、superはオーバーライドしているメソッドを呼び出す機能です。

class A
  def foo
    puts "A#foo"
  end
end

class B < A
  def foo
    super
    puts "B#bar"
  end
end

のとき、次のように出力されます。

B.new.foo 
=>
A#foo
B#bar

では、以下のような例だとどうでしょうか?

class A
  def foo
    puts "A#foo"
  end
end

module M
  def foo
     puts "M#foo"
  end
end

class B < A
  include M
  def foo
    super
    puts "B#bar"
  end
end

突然ですが、問題です。 B.new.foo() を実行したときに出力されるのは次のうちどれでしょうか?

(1)

M#bar

A#bar

B#bar

(2)

A#bar

B#bar

(3)

M#bar

B#bar

正解は・・・(3)

super はオーバーライドをするメソッドを呼び出すのであって、常に親クラスのメソッドを呼び出すわけではありません。名前に引きずられそうですね。

何もMix-inされていない場合、オーバーライドする親クラスのメソッドが呼び出されます。(なければ、その親クラスの親)といって、どれにもマッチしなければ method_missing が呼ばれます。通常は、NoMethodError になります。

オーバーライドされたメソッド呼び出しの階層を注意します。

include でモジュールをMix-inした場合は、元のクラスの上位に割り込みます。

メソッドの探索順にいえば、A->M->B になります。

メソッドの階層は ancestorsメソッドを使って調べます。上の例だと次の通り(Ruby2.1.xの場合)

irb> B.ancestors
=> [B, M, A, Object, Kernel, BasicObject]

Git 〜やらかしてしまった場合の戻し方〜

0

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

rickNo35です。
最近Gitでやらかしてしまった時の戻し方を記載します

環境

git 1.7.1

前提

masterブランチ
hogeブランチを保持

状態

hogeブランチにてmasterブランチをマージしたところ
conflictが発生修正してcommitしたが、
conflict発生以外のマージしたファイルもcommitしてしまった。
(自分は編集していないのに他の人の修正が自分hogeブランでコミットされてしまう)
別のブランチをマージしてしまった。
などを行いなおかつ気付かずに開発を続けてしまった時など色々

修正手順

# hogeブランチ移動
git checkout hoge
# hogeの変更履歴表示(別ターミナルで表示)
git log –stat master..hoge
# masterブランチに切り替わり最新にする
git checkout master
git pull
# 新しくブランチを作成+new/hogeに移動
git checkout -b new/hoge
# 別ターミナルで表示しているhoge変更履歴より必用なcommitのみ抜き出して入れる
git cherry-pick 取り出したいlogのcommitの番号
# hogeブランチを移動
git branch -m hoge old/hoge
# new/hogeブランチをhogeに置き換える
git branch -m new/hoge hoge
# hogeにpushする
# forceを付けないとコミット順番おかしいと言われるが強制的にforceでpushする(自分以外がいじっている場合はやらないほうがいい)
git push –force origin hoge
# 問題なければold/hogeブランチを削除
git branch -d old/hoge

image_submit_tagとsubmit_tagのパラメータの違いについて

0

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

初めまして、中西です。

今年社会人になったばかりの新人です。

今回は、自分が少し詰まった、image_submit_tagとsubmit_tagの挙動の違いについて紹介します。

環境

Rails 4.1.4

Ruby 2.1.2

image_submit_tagとsubmit_tagの違い

form_tag等でくくった中で、submitボタンを複数配置し、押下するボタンによって処理を変えたい場合、

アクションを1つしか設定できないことから、:nameのオプションをつけて、アクション内でパラメータにより処理を分けるといったことができます。

このとき、submit_tagとimage_submit_tagで渡されるパラメータに違いが生じます。

image_submit_tagとsubmit_tagの例

例えば下記のようなsubmitボタンを書いたとします。

view
= submit_tag 'HOGE', :name => 'hoge'

= image_submit_tag 'image/huga.png', :name => 'huga'

それぞれのボタンを押下した時に、期待するパラメータはparams[:hoge]とparams[:huga]です。

しかし、実際のパラメータの中身は下記のようになります。

paramsの中
"hoge"  => "HOGE"

"huga.x" => "12", "huga.y" => "10"

上記のように、image_submit_tagの場合、params[:huga]ではなく、

params[“huga.x”]とparams[“huga.y”]という2つのパラメータとなります。

どうも、ボタンの画像の左上を(x,y)=(0,0)として、横軸にx座標、縦軸にy座標となっており、

ピクセル単位でボタンの押下位置のx,y座標それぞれのパラメーターとして飛ぶようです。

まとめ

image_submit_tagで:nameのオプションを使う場合には、パラメータには十分注意しないといけないようです。

しかし、image_submit_tagも、1枚のボタン画像のなかで、押下位置により動作を変えたいといった場合には、使えるのかもしれません。

【Rails】barbyでバーコードを作成してPNGで表示する【バーコード】

0

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

「barby」を利用すると数字をバーコードにできたり、英数字をQRコードにして表示できるようになります。

今回はでデータURIスキームで画像表示する方法を紹介します。

この方法を使えば画像データを保存しなくて済みます。

 Githubとwikiのリンク

Github

https://github.com/toretore/barby

wiki

https://github.com/toretore/barby/wiki

 1.Gemfileに「 gem ‘barby’」と記述してbundle install

	$ vim Gemfile
	=================
	gem ‘barby’
	=================
	$ bundle install
	

 2.バーコード作成用のclassを作成

	class Barcode
	  require 'barby'
	  require 'barby/barcode/ean_13'
	  require 'barby/barcode/ean_8'
	  require 'barby/outputter/png_outputter'
	
	  def initialize(number, type = :ean_13)
	    @number = number.to_s
	    @type = type
	  end
	
	  # PNG形式でデータURIスキームを生成
	  def to_png_image
	    'data:image/png;base64, ' + Base64.encode64(Barby::PngOutputter.new(barcode(@type, @number)).to_png)
	  end
	
	  private
	
	  def barcode(type, data)
	    case type
	    when :ean_13 # 13桁の場合
	      Barby::EAN13.new(data)
	    when :ean_8 # 8桁の場合
	      Barby::EAN8.new(data)
	    end
	  end
	end
	

 3.controllerでの記述

	def index
	   @barcode = Barcode.new(491234567890)
	end
	

 4.viewでの記述

	<%= image_tag @barcode.to_png_image %>
	

他にもQRコードの作成やテーブルタグでの出力方法等もあったりします。詳しくは公式wikiをご確認ください。

[Ruby on Rails] enumerizeの使い方

0

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

Railsのgem、enumerizeの使い方のご紹介。

 列挙型とは?

列挙型とは、定数のリストを定義することができる型のことです。

使い道は様々ですが、ActiveRecordのvalueと組み合わせる方法が便利です。

 定数を利用する場合

例えば、DBのユーザテーブルに「性別」というカラムがあったとします。

性別には当然「男」と「女」の2パターンがあります。

この性別のフォームを作る場合どうしたらいいでしょうか?

まず、modelに定数を宣言する方法があります。

app/models/user.rb

class User < ActiveRecord::Base
  SEX = { male => '男', famale => '女' }.freeze
end

app/views/users/_form.html.haml

.form-inputs
  = f.input :sex, collection: User::SEX.invert, include_blank: false

値が少ない場合は上記でも問題なさそうですが、値が増えた場合やI18nで多言語化をしている場合、modelの記述が膨れ上がります。

 enumerizeを利用する場合

そこで列挙型の出番です。

Rails4.1からはActiveSupportでenumが使えるようになったのですが、I18nには非対応のようです。

ですので、gemのenumerizeが便利です。ActiveRecordとI18nに対応しています。

【GitHub/enumerize】

https://github.com/brainspec/enumerize

※インストール方法は上記リンク先を参照ください。

app/models/user.rb

class User < ActiveRecord::Base
  extend Enumerize

  enumerize :sex, in: [:male, :female]
end

※extendで上手く読み込まれない場合、includeしてみてください。

多言語化する場合は「enumerize」というネームスペースを使います。

config/locales/models/ja.yml

ja:
  enumerize:
    user:
      sex:
        male: 男性
        female: 女性

app/views/users/_form.html.haml

.form-inputs
  = f.input :sex, collection: User.sex.options, include_blank: false

valueも以下のように取得できます。

@user.sex_text
#=> 男性

 最後に

選択肢が多いカラム定義の際に特に便利かと思います。

他にも色々なメソッドが使えるようになっていますので、ぜひGitHubのページをご覧ください!

Rails開発でおすすめのRackサーバ「Pow」

0

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

Rackサーバ「Pow」のインストールと使用方法をご紹介。

 概要

【環境】
Mac OS X 10.6.8

POWって何?

PowとはMac OS Xで使用できる設定不要なRackサーバです。

では他のサーバに比べて何が便利なのか。

1. 面倒な設定が不要

 →ApacheやNginxだと設定ファイルを修正したりしないといけませんが、それが不要。

2, メンテナンスも不要

 →システムファイルを書き換えない自己完結型のサーバです。

3. 複数のサーバを起動しておくことが可能

 →railsサーバ等だと別アプリを起動する場合はポートをずらしたりしますが、Powでは必要ありません。

4. 自動停止/自動起動

 →15分間アクセスが無い場合は自動で停止します。そして次のアクセス時に自動起動。

 インストール方法

非常に簡単です。次のコマンドを実行するのみです。

$ curl get.pow.cx | sh

これだけでインストールは完了です。

 アプリケーションの登録

さてアプリケーションの登録です。まず手動で行う方法です。

ユーザのホーム直下に .pow というディレクトリが作られているので、

そこに登録したいアプリケーションルートのシンボリックリンクを貼るだけです。

$ cd ~/.pow
$ ln -s /path/to/myapp

この状態で http://myapp.dev/ にアクセスしてみましょう。サイトが表示されるはずです。

手動でも簡単ではありますが、もっと簡単な方法があります。

powder という gem を使います。

ますは powder をインストール。

$ gem install powder

そして登録したいアプリケーションルートに移動してコマンド実行。

$ cd /path/to/myapp
$ powder link

この powder link というコマンドで、先ほど手動でシンボリックリンクを貼ったことを自動でやってくれています。

ちなみに再起動も powder のコマンドから可能です。

$ powder restart

特に複数のアプリで連携する場合などに力を発揮するサーバだと思います。

導入も非常に簡単なのでおすすめです!

svnリポジトリの移動

0

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

rick No34です。
いまさらですが、svnリポジトリ移動の手順を記載します。

環境

サーバA(svnが有るサーバ)
サーバB(svnを移行するサーバ)
サーバC(サーバBのレプリサーバ)

手順

・Aサーバ
バックアップ

svnadmin dump リポジトリロケーション > バックアップ名
例:
svnadmin dump /var/lib/svn/hoge > hoge.dump

hoge.dumpをサーバBへscp等で送信

・Bサーバ
svnディレクトリ作成

mkdir /var/lib/svn

svnリポジトリ用ディレクトリ作成

mkdir /var/lib/svn/hoge

ディレクトリ権限変更

chown -R apache:apache /var/lib/svn/hoge
daemonだったりもする

バックアップ移動

mv ./hoge.dump /var/lib/svn

svnリポジトリ作成

svnadmin create /var/lib/svn/hoge/

リストア

svnadmin load /home/svn/hoge/ < hoge.dump

単一サーバの場合は、これで終了

・Cサーバ
svnディレクトリ作成
(Bサーバ同様省略)
svnリポジトリ用ディレクトリ作成
(Bサーバ同様省略)
ディレクトリ権限変更
(Bサーバ同様省略)
SVNリポジトリ作成
(Bサーバ同様省略)
設定ファイル作成

cd /var/lib/svn/hoge/hook
vi pre-revprop-change

#!/bin/sh
exit 0

vi pre-revprop-change.bat

exit 0

初期化

svnsync init svn+ssh://バックアップ先//var/lib/svn/hoge svn+ssh://バックアップ元//var/lib/svn/hoge

※ssh接続先ポートが変更されている場合

vi ~/.subversion/config

[tunnels]
ssh_hoge = ssh -p 8888

これでsvn+sshをsvn+ssh_hogeに変える

権限変更

chmod +x /var/lib/svn/hoge/hooks/pre-revprop-change

同期

svnsync sync svn+ssh://バックアップ先//var/lib/svn/hoge

バッチ設定
同期のコマンドをバッチで設定、もちろんパスワードレスの状態にしておく
終了

その他

・差分だけダンプ

svnadmin dump /var/lib/svn/hoge -r 12039:12040 –incremental > hoge.dump

・差分リストア

svnadmin load /var/lib/svn/hoge/ < hoge.dump

・リビジョン確認方法

/usr/bin/svnlook youngest /var/lib/svn/hoge

・リビジョン強制戻し

cd /var/lib/svn/hoge/db
rm /revs/x/消したいリビジョン
vi current # 直したリビジョンに書き直す
echo > rep-cache.db # キャッシュ削除
rm revprops/x/

注意点

現リビジョンが100で、後から90~91の差分リストをした場合
リビジョンの90~91が更新されるわけではなく、101,102として更新される。

Apache HTTP Serverで使用しているOpenSSLのバージョンを確認する3つの方法

0

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

Apache HTTP Serverで使用しているOpenSSLのバージョンを確認する方法を3つご紹介します。

 HTTPのレスポンスヘッダを見る

レスポンスヘッダのServerの値を確認します。

$ wget  -S -O - http://localhost 2>&1|grep Server
  Server: ・・・・・ OpenSSL/1.0.1j 

ただし、apache側の設定で

ServerTokens ProductOnly

としている場合Serverは表示されません。

 mod_ssl.so の中身を見る

stringsコマンドを使うとバイナリファイル中の文字列を抽出できます。

mod_ssl.soファイルの中身を見てみます。

$ strings /usr/local/apache2/modules/mod_ssl.so |grep 1.0.1
OpenSSL 1.0.1i 6 Aug 2014

ただしここで表示されるのはapacheがビルドされた時点の情報で、現在このバージョンで動作しているとは限りません。

 mod_infoを使って確認する

mod_infoを使います。

インストールなどがされていなければ適宜設定をしてください。(アクセス元を限定するなど注意が必要です)

そのうえで下記のようなコマンドでバージョンの確認ができます。

$ wget -q -O - http://localhost/server-info |grep 1.0.1|sed "s/.\+\(OpenSSL\/[^ ]\+\).\+/\1/"
OpenSSL/1.0.1j

vagrant で簡単に環境をつくる-2

0

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

こんにちは、bibioです。まだまだぴちぴちです。

前回に続きvagrantについてです。

仮想イメージを保存する

vagrant up した仮想環境はそれぞれVagrantfileのあるディレクトリ

の下に保存されています。そのため、それをBOX形式にエクスポートする

ことができます。

$ vagrant package

注意)仮想マシンは停止されます。また、実行に時間がかかります。

デフォルトでは package.box という名前で保存されます。

仮想イメージを box に追加する

作成したイメージは box にいれておくと、使いまわすときなど便利です。

$ vagrant box add --name my_box package.box

もう package.box は不要ですので削除してしまいましょう。

今後は Vagrantfile の config.vm.box に作成した名前を追加するだけです。

よくあるトラブル

/vagrant がマウントされなくなった

yum update などで kernel のバージョンがかわるとマウントされなくなります。

vagrant up 途中でエラーがでてても、仮想マシンは起動していますのでsshで

ログインしてモジュールを作成しなおすことで回避できます。

l $ vagrant ssh
v $ sudo /sbin/service vboxadd setup

その後再度 reload してあげればマウントされていると思います。

Vagrantfile の中身を編集したが反映されない

vagrant reload をしましょう。

vagrant で簡単に環境をつくる

0

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

はじめまして、bibioです。中途入社のぴちぴちです。

入社早々開発環境を作ったという流れで、ぎりぎりRubyつながりなvagrantの操作をおさらいします。

そもそもvagrantって何ですか?

VirtualBox(VMwareも使えますが確か有償)をコマンドラインから簡単に動作できるようにしたツールです。

https://www.virtualbox.org/

https://www.vagrantup.com/

ホスト環境は Macですが、Windowsでも動きます。

メリット

  • 設定ファイルは Ruby で記述されている
  • OSがインストールされた仮想イメージが簡単に利用・共有できる
  • chef の検証に便利

デメリット

  • プラグインの使い方がわかりにくい
  • 初期値のメモリが少ない(512MB)のでコンパイル中にたまに固まる

キーワード

boxOSインストール済みの仮想化ファイルprovider仮想ソフトウエアの種類

前提環境と準備

今回は VirtualBox を使います。

はじめに VirtualBox と Vagrant をダウンロードしてインストールします。

https://www.virtualbox.org/

https://www.vagrantup.com/

流れ

host $ mkdir vagrant; cd vagrant
host $ vagrant init
host $ vi Vagrantfile
host $ vagrant up
host $ vagrant ssh
guest > 

基本的にこれだけです。初回の vagrant up で chef/centos-6.5 の

BOX がダウンロードされるので時間と帯域を消費します。

また、ダウンロードしたBOXは保存されるので、次回以降 chef/centos-6.5 を

使う場合は基本的にはダウンロードされません。

upした段階で VirtualBox をたちあげると仮想マシンが生きていることが確認できます。

なお、仮想マシンは up 時に BOX から複製されるので、元のBOXは変更されません。

設定ファイルの編集

Vagrantfile という設定ファイルを編集することでカスタマイズが可能です。

最低限必要なオプションは config.vm.box だけ。

VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # CentOS 6.5 を入れる
  config.vm.box = "chef/centos-6.5"

  # プライベートネットワーク設定するとホストからアクセス
  config.vm.network "private_network", ip: "192.168.33.10"

   # 仮想マシンのカスタマイズ
   config.vm.provider "virtualbox" do |vb|
     vb.gui = false 
    # CPU2コア,メモリ1GBを割り当てる。 ioapic がないとうまく動かないみたい
     vb.customize ["modifyvm", :id, "--memory", "1024", "--cpus", "2", "--ioapic", "on"]
   end
end

ssh でログイン

初期値のホストとポートは 127.0.0.1:2222 です。

秘密鍵は $HOME/.vagrant.d/insecure_private_key です。

パスワード未設定なので気になったら自分の秘密鍵に変更してください。

ssh の設定は以下のコマンドで確認できます。

$ vagrant ssh-config
Host default
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /home/bibio/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

おまけですが、秘密鍵から公開鍵を作る方法です。

$ ssh-keygen -y -f .ssh/id_rsa

仮想マシンを停止/サスペンド/削除

操作もコマンドラインからできます。

停止
$ vagrant halt
サスペンド
$ vagrant suspend
削除

容量を圧迫するので使わなくなった仮想マシンは削除しましょう。

$ vagrant destroy

なお、BOX は削除されません。

さらにBOXの複製や共有もできますが、今回はここまで。

VirtualBoxの 「for reading: -102(File not found.) E_FAIL (0x80004005)」エラー

0

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

VirtualBoxは下記のエラーで、仮想マーシンへのアクセスが出来ません。■エラーメッセージ
Runtime error opening ‘C:\Users\xxx\VirtualBoxVMs\xxx\xxxx.vbox’ for reading: -102 (File not found).
:
:
:
E_FAIL (0x80004005)

■発生経緯
VirtualBoxが起動して、仮想マーシンへアクセスしているままで、
パソコンが自動更新で、勝手に再起動してしまった。

探していましたが、エラーが発生するxxxx.vboxファイルはどこにもありません。
VirtualBoxを修復しても、再インストールしても、PCシステムが更新前のポイントに戻しても治せません。

仮想マーシンを再作成するしかないかと困っているところ、
C:\Users\xxx\VirtualBoxVMs\xxxにxxxx.vbox-tmpというファイルがあったことに気がつきました。
試しに、このファイルをxxxx.vboxにrenameにして、VirtualBoxを再起動してみたら、
仮想マーシンへのアクセスができるようになりました。

最近人気な記事