ホーム ブログ ページ 39

Rails.cacheでキャッシュ処理してみた

0

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

よく閲覧されるページで何度もDBを読み込むのは、負荷がかかったりしていいとは言えません。 なのでキャッシュ処理を使用して、DBアクセスを減らしサクサク動けるようにしたいです。 そこでRailsでは容易にキャッシュ処理ができるのでやってみました。

class BlogController < BaseController
  before_action :load_paper, :load_picture, only: [:show]
  # キャッシュの保有期間を設定
  CACHE_EXPIRE_TIME = 1.day.freeze

  def show
    ・・・・・
  end

  private

  def load_paper
    # Rails.cache.readで読み込む
    @papers = Rails.cache.read(cache_key(:paper))
    # なかったらRails.cache.writeで書き込む
    unless @papers
      @papers = Paper.all
      Rails.cache.write(cache_key(:paper), @papers, expires_in: CACHE_EXPIRE_TIME)
    end
  end

  def load_picture
    @pictures = Rails.cache.read(cache_key(:picture))
    unless @pictures
      @pictures = Picture.all
      Rails.cache.write(cache_key(:picture))
    end
  end

  # keyが被らないようにする
  def cache_key(type = nil)
    [
      self.class.name.underscore,
      type
    ].join('')
  end
end

メソッド化などをしなければキャッシュ処理は3~4行追加するだけでできるので非常に便利です。

またRails.cache.fetchを使用するとさらに短くなります。
fetchはキャッシュがあったらそのまま返し、なかったらキャッシュを生成して返すという処理が行われます。

  def load_paper
    @papers = Rails.cache.fetch(cache_key(:paper), expires_in: CACHE_EXPIRE_TIME) do
      Paper.all
    end
  end

翻訳されてないですが、RailsGuidesで詳しく載っているのでこちらを見るのもいいかもしれないです。

[rails] Jpmobileを使用する際の注意点 Edit

0

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

スマフォでPC表示させているときの条件に注意。

Jpmobileの概要

RailsでPCサイトと共にスマフォサイトを作成する場合に便利なGemとして、JpmobileというGemがあります。

このGemを使うことで、アクセス端末に応じてviewを切り替えることができます。

すなわち、Jpmobileを使用することで、PCからアクセスされた場合にはPC用のviewを表示させ、スマフォからアクセスされた場合にはスマフォ用のviewを表示させることを、Webサイトの開発者が意識することなく実装できます。

また、スマフォからのアクセスかどうかを「request.smart_phone?」のように判定することができるようになります。

ここで、スマフォでアクセスした場合であっても、PC用のviewを表示したいユーザーがいることを考慮して、「PCサイトを表示する」のようなリンクを用意することがあると思います。

この場合には、「disable_mobile_view!」メソッドをコールすることで、PCサイトを表示させることができます。

※恐らく、このようなリンクがクリックされたことを、cookieやsessionに保存し、ページ遷移した後であっても、PCサイトを表示するように実装されるかと思います。

問題点

スマフォからのアクセスに対してPCサイトを表示させている状態であっても、request.smart_phone?の結果は「true」になります。

すなわち、viewが絡む部分(*1)に関して「request.smart_phone?」で条件判定をすると、意図しない動作になる可能性があります。

(*1) controllerでインスタンス変数に値を設定する場合等も含む。

例えば、

  • PCの場合 → 12個のレコードをインスタンス変数に設定
  • スマフォの場合 → 8個のレコードをインスタンス変数に設定

とすべき場合、本来であれば、

  • PCアクセス(PC用の表示) → 12個のレコードがインスタンス変数に設定される
  • SPアクセスでスマフォ用のを表示 → 8個のレコードがインスタンス変数に設定される
  • SPアクセスでPC用の表示 → 12個のレコードがインスタンス変数に設定される

となって欲しいところです。

しかしながら、controllerで、

def index
  count = request.smart_phone? ? 8 : 12
  @records = TestTable.where(...).limit(count)
end

のように、「request.smart_phone?」を使用してしまうと以下のようになってしまいます。

  • PCアクセス(PC用の表示) → 12個のレコードがインスタンス変数に設定される
  • SPアクセスでスマフォ用のを表示 → 8個のレコードがインスタンス変数に設定される
  • SPアクセスでPC用の表示 → 8個のレコードがインスタンス変数に設定される(←12個になっていない!!)

■ 対策

このため、viewに絡む部分に関しては、

  • 判定1:アクセス端末によって切り替えるのか?
  • 判定2:PC用のviewとスマフォ用のviewのどちらを表示しているかによって切り替えるのか?

を常に意識しないと思わぬバグに繋ります。

先程の例では、判定2でやらなければいけません(判定方法は、どちらのviewを表示しているかの情報が保存されたcookieやsessionを参照して判定することになると思われます)。

なお、判定1が必要になる例としては「SPアクセスでPC用の表示をしているときに、スマフォ用のviewに戻すためのリンクを表示する場合(PCでアクセスして来た人に対してスマフォ用のviewを表示することは通常ない。スマフォのときにのみ有効。但し、この例の場合には、PC用のviewを表示している場合にのみ表示させる必要有り)」が挙げられます。

enumで数値型カラムを作る際に、テストデータを作る時に注意すること

0

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

Railsの4.1でenumが使えるようになりました。

一般的には文字列型のカラムを用意して

class User < ActiveRecord::Base
  enum status: { :awake, :sleep, :dead }
end

と書いて

user = User.new(status: :awake)
user.awake? # => true

という使い方をしますが、使うカラムを数値型にすることで

class User < ActiveRecord::Base
  enum status: { awake: 1, sleep: 2, dead: 99 }
end

とすると

user = User.new(status: 1)
user.awake? # => true

とかできるようになります。業務アプリで定数処理しているところが捗りますね。

さて、これのテストを書くときにfactorygirlでモデルを作ろうとして、

FacrotyGirl.define do
  factory :user do
    status 1
  end
end

と書いたら

 Failure/Error: user = build(:user)

 ArgumentError:
  '1' is not a valid status

とエラーが出てしまいました。困る…。
こういう場合、

FacrotyGirl.define do
  factory :user do
    status :awake
  end
end

と名前のほうをfactoryに書けばいいです。

Macで自動作成される隠しファイルを削除

0

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

Macだと勝手に隠しファイルが自動作成される場合がある。

「._.hogehoge」みたいな感じのファイル名。

見付ける度に、適当にfindしてrmするコマンドを実行していたりするが、
たまにvimで編集中に、現在のディレクトリ以下の
上記ファイルを全て削除したくなることがあるので、
vim scriptの勉強がてらscriptを作成してみた。

function! s:DeleteFilelist(list)
    let target = a:list

    let num = len(target)
    if 0 == num
        echo "No target file"
        return
    endif

    echo "The deleted file is shown."
    let j = 0
    while j < num
        echo target[j]
        let j = j + 1
    endwhile
    let yn = input("OK? (y or n) -> ")
    echo "\n"

    if "y" == yn
        let j = 0
        while j < len(target)
            call delete(target[j])
            let j = j + 1
        endwhile
        echo "Deleted!!"
        return
    endif
    echo "Canceled."
endfunction

function! s:DeleteMacAutoMakeFiles()
    let target = []
    let globout = glob("**/._*") . "\n"
    while globout != ''
        " Process one file at a time
        let name = strpart(globout, 0, stridx(globout, "\n"))

        " Remove the extracted file name
        let globout = strpart(globout, stridx(globout, "\n") + 1)

        if name == ''
            continue
        endif

        call add(target, name)
    endwhile

    call s:DeleteFilelist(target)
endfunction

command! -nargs=0 DeleteMacAutoMakeFiles :call s:DeleteMacAutoMakeFiles()

vim scriptでやるなよ、って気もするが…。

[scala] [vim] vimでplayの開発環境を構築する

0

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

本記事の対象者

  • Railsの開発をvimでやっている。
  • vimのpluginとして、unite-railsを使っている。
  • Play(Scala)でもRailsと同じように開発したい人向け。

ちなみに、unite-railsは、vimのuniteというプラグイン向けのプラグイン。

よって、本記事は、vimのuniteを使っている人向け。

やりたい事

Playのプロジェクト配下のファイルを開いているときには、プロジェクト配下のソースの選択をuniteインターフェースで使いたい。

対応の概要

  • 項目1:Play用のuniteインターフェースを作成する。
  • 項目2:Playのプロジェクト配下のファイルを開いているときには、ファイルタイプに「play」が含まれるようにする。
  • 項目3:ファイルタイプに「play」が含まれているときに、play用のunite-pluginのキーバインドを有効にする。

【項目1】Play用のuniteインターフェースを作成する。

unite-railsを参考にunite-playを作成する。

参考までに、私が作成したunite-playの中は以下のようになっている。

% tree unite-play
unite-play/
├── README
├── autoload
│   └── unite
│       ├── kinds
│       │   └── bundled_gem.vim
│       └── sources
│           ├── play
│           │   ├── collector
│           │   │   ├── config.vim
│           │   │   ├── controller.vim
│           │   │   ├── javascript.vim
│           │   │   ├── model.vim
│           │   │   ├── root.vim
│           │   │   ├── route.vim
│           │   │   ├── stylesheet.vim
│           │   │   ├── test.vim
│           │   │   └── view.vim
│           │   └── helper.vim
│           └── play.vim
└── doc
    └── unite-play.txt

7 directories, 14 files

普通の開発者であれば、unite-railsの各ファイルの中身を参照すれば、簡単にplay用に修正できるはず。

プロジェクトのルートディレクトリ配下のファイルを全て一覧かするものを追加している(root.vim)。root.vimの中身はこれ↓。

function! unite#sources#play#collector#root#candidates(source)
  let target = a:source.source__play_root
  return unite#sources#play#helper#gather_candidates_file(target)
endfunction

controller.vimの中身はこれ↓。

function! unite#sources#play#collector#controller#candidates(source)
  let target = a:source.source__play_root . '/app/controllers'
  return unite#sources#play#helper#gather_candidates_file(target)
endfunction

ここまで見れば、どういう感じで修正さればよいかは分かるはず。

正しく修正することで、例えば、

  :Unite play/controller

でapp/models配下のファイル一覧を表示させたりできる。

後は、上記コマンドを適当なキーにバインドすればOK。

【項目2】Playのプロジェクト配下のファイルを開いているときには、ファイルタイプに「play」が含まれるようにする。

projectlocal」というvimのpluginを導入する(開発元のブログはこちら)。

「.vimrc」に以下の設定を追加する。

  let g:projectlocal#projectfile = get(g:, 'projectlocal#projectfile', '.projectfile')

そして、Playのプロジェクトのルートディレクトリに以下のファイルを置く。

% cat .projectfile
play

この例では、「.projectfile」が置かれているディレクトリ配下のファイルを開くとファイルタイプに「play」が含まれるようになる。

【項目3】ファイルタイプに「play」が含まれているときに、play用のunite-pluginのキーバインドを有効にする。

「.vimrc」に以下のような設定を追加する。

function! UnitePlaySetting()
    nnoremap <buffer><c-w><c-r>co :<c-u>Unite play/controller<cr>
    nnoremap <buffer><c-w><c-r>tp :<c-u>Unite play/root<cr>
endfunction

aug HogeAutoCmd
    au FileType *play* call UnitePlaySetting()
aug END

【おまけ】scalaのファイルを編集しているときには、ファイルタイプに「scala」が含まれるようにする。

vim-scalaというvimプラグインを導入する。

上記設定を全ておえ、当該プラグインが有効になれば、Playプロジェクト配下のscalaのファイルを開くと、ファイルタイプが「project.scala.play」となる。

無事に、scalaとplayのファイルタイプが含まれている。

【Rails / gem nested_form】nested_formへsortableの導入【jquery-ui/sortable

0

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

accepts_nested_attributes_for用のフォームをサポートしてくれる「nested_form」にドラッグ&ドロップで並び順を変更できる「jquery-ui/sortable」を導入する方法を記述します。

事前準備

1.Gemfileに追記
$ vim Gemfile

gem 'jquery-rails'
gem 'jquery-ui-rails'
gem 'nested_form'

2.モデルにaccepts_nested_attributes_forを追記
例としてBlog-< Entryな関連でEntryが並び順に使用するカラム(position)を所持

$ vim app/models/blog.rb

has_many :entries
accepts_nested_attributes_for :entries, allow_destroy: true

$ vim app/models/entry.rb

belongs_to :blog

3.コントローラにpositionパラメータを取得できるように追記
$ vim app/controllers/blogs_controller.rb

def blog_params
  params.require(:blog).permit(
    ....,
    entries_attributes: [
      ...,
      :position
    ]
  )
end

viewでの記述

$ vim app/views/blogs/_form.slim

= nested_form_for(@blog, url: ...) do |f|
  ....
    table#entries.table.table-striped.table-sortable
      = f.fields_for :entries, wrapper: false
    br
    .pull-right.
      = f.link_to_add '追加', :entries, data: { target: '#entries' }, class: 'btn btn-default'

$ vim app/views/blogs/_entry_fields.slim

tr.fields.form-group
  td ...
  ...
  td
    .pull-right
      = f.link_to_remove '削除', class: 'btn btn-danger'

  = f.hidden_field :position, class: :position

js.coffeeでの記述

$ vim app/assets/javascripts/blog.js.coffee

$ ->
  ...
  # 並び替え
  $('.table-sortable').sortable
    axis: 'y',
    items: '.fields',
    update: (e, ui) ->
      # ドラッグ&ドロップしたら各entryのhidden_fieldに現在の位置を入れる
      $('.position').each ->
        $(this).val($('.position').index($(this)) + 1)

以上でフォームをsubmitした時にドラッグ&ドロップで変更したpositionパラメータが取得できる様になります。

[rails] FactoryGirlを使用する際の注意点

0

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

rspecで思うように動かないケースがあってハマる可能性有り。

今回の問題を抽象的に表現すると

FactoryGirlを用いてインスタンスを生成するときにおいて、以下の条件を全て満たす場合には、生成されたインスタンスに意図した値が設定されない場合があります。

  • 条件1:所定のattributeに対して値を設定する方法が「複数」存在する。
  • 条件2:当該attributeに対して、上記「複数の方法のうち少なくとも2つ以上の方法」で値を設定する。

多分、上記表現では、抽象的すぎて意味不明だと思われるため、以下に具体例を示します。

事象の具体例

ケース1

store = FactoryGirl.create(:store)
p store.store_category
=> 1

ケース2

store = FactoryGirl.create(:store, store_category: 2)
p store.store_category
=> 1

2にならない!!

参考

以下の場合には、当然、値を代入できます。

store = FactoryGirl.create(:store)
store.store_category = 2
p store.store_category
=> 2

前提

  • 前提1:Storeテーブルには、store_category(カテゴリ名)というattributeが存在する。
  • 前提2:Storeクラスには、以下のようなメソッドが定義されている。
class Store < ActiveRecord::Base
           :

  # カテゴリ名でカテゴリコードに値を代入
  def store_category_name=(category_name)
    store_category = convert(category_name)
  end

  # カテゴリ名をカテゴリコードに変換
  def convert(name)
           :
  end

           :
end
  • 前提3:FactoryGirlを用いて、以下のように定義されている。
FactoryGirl.define do
  factory :store do
    store_category_name 'Japanese Restaurant'
  end
end

※「Japanese Restaurant」は、カテゴリコードに変換すると「1」

「今回の問題を抽象的に表現すると」との対応関係

上記条件1でいうところの、

「所定のattribute」は「Storeテーブルのstore_category」であり、

「所定のattributeに対して値を設定する方法」として、

  • 方法1:store.store_category = 1
  • 方法2:store.store_category_name=’Japanese Restaurant’

の2つがある。

どうすれば代入できるか

ケース3

store = FactoryGirl.create(:store, store_category_name: 'French Restaurant')
p store.store_category
=> 2

※「French Restaurant」は、カテゴリコードに変換すると「2」

原因

FactoryGirlのGemの中身を確認した訳ではありませんので、表面的な事象に基づいた話になります。

恐らくFactoryGirlの内部で、上記各ケースが以下のようになっていると推定されます。

・ケース1:「store = FactoryGirl.create(:store)」

Store.new(store_category_name: 'Japanese Restaurant')

・ケース2:「store = FactoryGirl.create(:store, store_category: 2)」

Store.new(store_category: 2, store_category_name: 'Japanese Restaurant')

・ケース3:「store = FactoryGirl.create(:store, store_category_name: ‘French Restaurant’)」

Store.new(store_category_name: 'French Restaurant')

そして、Storeのinitializeの中で、渡されたHashの順番にattributeを更新していき、

ケース2では、

代入1回目:最初にstore_categoryに2が入る
代入2回目:その後にstore_category_nameにJapanese Restaurantが渡されて、store_categoryに1が入る

となっているのだと思います。

「今回の問題を抽象的に表現すると」との対応関係

このように、ケース2では、代入1回目と代入2回目で異なる方法(「複数の方法のうち少なくとも2つ以上の方法」)で、値を設定していることから条件2を満たすことになり、意図した値が設定されていません。

ケース1, 3では、1つの方法でのみ値を設定しているため、条件2を満たすことなく、意図通りの値が設定されます。

対策

今のところ、各ソースコードの確認や実際にテストする際に値が意図したものに設定されているか等を確認しながら気を付けるくらいしか思い付きません。

こういう問題があるということを頭の片隅に入れておけば、問題が生じたときのデバッグが早くなると思います。

参考

selectable_attrというgemを使うと、所定のattributeに値を設定するために複数のメソッドが追加されます。

selectable_attrの対象としたattributeに対してFactoryGirlを使って値を初期化する場合には気をつけましょう。

最後に

rspecを記載したときには、各オブジェクトの値が意図したものになっているかを、しっかりと確認しましょう。

そうしないと意味の無いテストを行ってしまっている可能性があります。

Vimでメモ

0

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

序論

サーバ作業をしたり、リモートから接続したりすることを考えると、メモは、CUIで開ける形式で残しておくとイザというときに役に立つ。

私が愛用しているのは、howm(Hitori Otegaru Wiki Modoki)というパーソナルで使うWikiのようなメモ環境。

howmについて

howmには、以下の特徴がある。

  • 特徴1:メモの作成時に、今日の日付及び現在の時間がファイル名に指定される。
  • 特徴2:所定のディレクトリ配下を再帰的に全文検索することができる。

howmは、元々、Emacsのpluginとして公開されていたが、vimでもpluginを作成してくれた方がいる。

私も最初は、EmacsやMeadowでhowmを使用していたが、段々vimで全てを完結するようになり、howmもvimのpluginのものに置きかえるようになった。

使用しているpluginは、QFixHowmである。

QFixとは、vimの検索機能のquickfixのことだと思われる。

設定などは、上記サイトを確認して頂ければよいが、私は、カスタマイズしてちょっとだけ異なる使い方をしている。

カスタマイズ

それは、所定のディレクトリを用途に応じて切り替えて使っている点である。

これは、以下の用途でディレクトリを分けたいときに便利である。

  • 所謂メモのディレクトリ
  • 日報用のディレクトリ

日報には、比較的同じような内容の記録が残ることが多い。
例えば、複数日にわたるタスクや、定例作業などである。

このため、全文検索をするときに、日報が検索対象になってしまうと本当に欲しいメモに辿り着けないことがしばしば出て来て困った経験から、通常は日報を検索対象にしないようにすることにした。

以下にQFixHowmにおけるディレクトリ切り替えの設定を記す。

  • 通常のメモに切り替える場合は、Prefixキーの後に「,1」を押下する。
  • 日報用メモに切り替える場合は、Prefixキーの後に「,2」を押下する。

なお、最後に「QFixHowmEnvMain()」をコールすることで、vim起動時に通常のメモが選択されるようにしている。

exe "nnoremap <silent> " . QFixHowm_Key . ",1 :call QFixHowmEnvMain()<cr>"
exe "nnoremap <silent> " . QFixHowm_Key . ",2 :call QFixHowmEnvDailyReport()<cr>"

function! QFixHowmEnvMain()
    let g:howm_dir            = '~/memo'
    let g:howm_filename     = '%Y/%m/%Y-%m-%d-%H%M%S.howm'

    " 設定関数呼び出し
    silent! call QFixHowmSetup()
    echo g:howm_dir
endfunction

function! QFixHowmEnvDailyReport()
    let g:howm_dir            = '~/daily_report'
    let g:howm_filename     = '%Y/%m/%Y-%m-%d_daily_report.howm'

    " 設定関数呼び出し
    silent! call QFixHowmSetup()
    echo g:howm_dir
endfunction

silent! call QFixHowmEnvMain()

リニューアルをしたDoRubyの3つの目的

0

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

お久しぶりです。何年ぶりの投稿になるでしょうか。。。 さて、Rubyエンジニアによる技術情報配信を目的に運営しておりました「DoRuby」ですが、老朽化や内部SEO対策などが薄れなど諸々の課題をクリアするため社内有志を募ってリニューアルいたしました。

Rubyの技術情報配信を目的にしておりましたが、途中からRubyだけではなくJava、PHP、Apache、JMeter、GAなどコンテンツの枠を広げて運営してまいりました。2008年くらいから公開し、紆余曲折あり運営を続けてまいりましたが、諸々の課題をクリアするためにリニューアルを行いました。

「DoRuby」は新しく以下の3つの目的を持ち、生まれ変わりました。

●「DoRuby」の新しい3つの目的

  1. 記事を役立ててもらい、社会に貢献すること
  2. アピリッツ社員が自身が保有するノウハウを自由に発信できるようにすること
  3. 社員にも一般利用者にもアピリッツという会社をもっと知ってもらうこと

今後もRubyをはじめとした技術情報やマーケティング関連情報など枠を広げて情報を発信できればと考えておりますので、どうぞよろしくお願いいたします。

WEBrickのURI長上限を拡張する

0

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

WEBrickのURI長上限を拡張する

WEBrickで扱うことが出来るURI長の上限は2048バイトに制限されています。

上限を超えた場合は

Request-URI Too Large
WEBrick::HTTPStatus::RequestURITooLarge

というようなエラーメッセージが表示されます。

しかし、ローカルで開発している場合に、どうしてもその上限を緩和したくなる場合があると思います。

そんな場合はWEBrickのソースコードに記載されている制限値を直接変更することで、好きな値に変更することができます。

rbenvを利用してruby 2.3.1をインストールしている場合、

~/.rbenv/versions/2.3.1/lib/ruby/2.3.0/webrick/httprequest.rb の 415行目に記載されている

MAX_URI_LENGTH = 2083 # :notoc:

の数値を変更します。

Apacheのrestartやgraceful、stopなどの違い

0

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

apachectlのrestartやgraceful、
httpdのrestartやgraceful、
/etc/init.d/httpdのrestart…、
それぞれの微妙な違いをまとめました。

apachectl graceful
httpd -k graceful※どちらも同じ。
apachectl gracefulを実行すると、内部でhttpd -k gracefulが呼ばれる(後述)
子プロセスは現在のリクエストを処理した後、終了する。親プロセスは設定ファイルを再読み込みし、ログファイルを開き直す。子プロセスが徐々になくなり、替わりに新しい子プロセスが起動する。【注意点】
設定ファイルに誤りがあったり等で親プロセスが再起動せず終了した場合、 子プロセスが放置されたりする場合がある(→再起動時に問題となる可能性がある)
ので、再起動前にhttpd -tで構文チェックをした方がよい。
apachectl restart
httpd -k restart※どちらも同じ。
apachectl restartを実行すると、内部でhttpd -k restartが呼ばれる(後述)
子プロセスを即座にkill。親プロセスは終了しない。親プロセスは設定ファイルを再読み込みし、ログファイルを開き直す。その後新しい子プロセスを起動。→ログを見るとHUPシグナルが渡されたことが確認できます。
/etc/init.d/httpd restart※httpd -k restartとは別もの。
起動スクリプト内で定義されたstop→startが実行される。
子プロセスを即座にkillし、全て終了後、親プロセスも終了。(stop)その後起動。(start)→ログを見るとTERMシグナルが渡されたことが確認できます。※Apacheのインストールディレクトリがデフォルトと違う場合は、
/etc/init.d/httpd 内でhttpd実行ファイルの場所を修正する必要があります。

「apachectl restart」と「httpd -k restart」は同じ

apachectlに特定の引数を渡すと、内部で「httpd -k 引数」が実行されます。

特定の引数とは、
start | stop | restart | graceful | graceful-stop
です。

# less apachectl
-------------
  ・
  ・
case $ARGV in
start|stop|restart|graceful|graceful-stop)
    $HTTPD -k $ARGV
    ERROR=$?
    ;;
startssl|sslstart|start-SSL)
    echo The startssl option is no longer supported.
    echo Please edit httpd.conf to include the SSL configuration settings
    echo and then use "apachectl start".
    ERROR=2
    ;;
configtest)
    $HTTPD -t
    ERROR=$?
    ;;
status)
    $LYNX $STATUSURL | awk ' /process$/ { print; exit } { print } '
    ;;
fullstatus)
    $LYNX $STATUSURL
    ;;
*)
    $HTTPD $ARGV
    ERROR=$?
esac

exit $ERROR
-------------

これらの引数が渡された場合は、 httpdにそのまま引数が渡され
挙動は上記表のとおりとなります。

また、「apachectl restart」と「apachectl -k restart」も同じです。

「httpd -k restart」と「/etc/init.d/httpd restart」は別もの

どちらもhttpdを再起動しますが、処理プロセス(手続き)が異なるため挙動も異なります。

「httpd -k restart」は、httpdバイナリ(実行ファイル)内の処理によって、
「/etc/init.d/httpd restart」は、/etc/init.d/httpd(起動スクリプト)内の処理によって
再起動されます。

それぞれの処理内でkillの仕方が違う(渡されるシグナルが違う)ようで、

httpd -k restartSIGHUP
/etc/init.d/httpd restartSIGTERM
/etc/init.d/httpd reloadSIGHUP

となっているようです。

/etc/init.d/httpd は、httpd実行ファイルを起動するためのスクリプトファイルです。
手動インストール等でインストール場所が異なる場合は/etc/init.d/httpdを編集して
httpd実行ファイルの場所を修正する必要があります。

詳細は公式のドキュメントに記載されています。
https://httpd.apache.org/docs/2.2/ja/stopping.html

CentOSサーバ構築〜初期設定〜

0

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

rickNo41です。 サーバを構築する時にする初期に設定した方がいいことを少し紹介します。

環境

CentOS7
※以下設定は全てrootで実施

時刻設定

yum install -y chrony
systemctl start chronyd.service
// しばらくすると時刻が正しくなります。

コマンド履歴保存期間変更・日時付与・vim

vim /etc/bashrc
—–
// 一番下に追加
export HISTSIZE=100000
export HISTTIMEFORMAT=’%Y-%m-%d %T ‘;
export EDITOR=/usr/bin/vim
—–
source ./bashrc
// 日時が表示されている
// 日付設定前のコマンドの日時は全て日付設定時になる
history

sar監視間隔変更

vim /etc/cron.d/sysstat
—–
// 変更
#*/10 * * * * root /usr/lib64/sa/sa1 1 1
* * * * * root /usr/lib64/sa/sa1 1 1
—–

sar監視保持日数変更

vim /etc/sysconfig/sysstat
—–
// 変更
#HISTORY=28
HISTORY=30
—–

SElinuxm無効化(変更後再起動必用)

vim /etc/sysconfig/selinux
—–
// 変更
#SELINUX=enforcing
SELINUX=disabled
—–
// Disabledでok
getenforce

ローカル開発環境でGoogleアナリティクスを動作確認する

0

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

ローカル開発環境でGoogleアナリティクスの動作確認をしたいが、

Googleアナリティクスのプロパティを作成する際、ウェブサイトのURLが必須となっていたので、どう設定すればいいのか色々試してみました。

【環境】

Vagrant + VirtualBox

CentOS 7

Ruby on Rails 4.2

ホストOS windows10

 前提

Googleアカウントを作成済みであること

 操作手順

Google Analyticsのページを開き、

https://www.google.com/intl/ja_jp/analytics/

・アカウントの作成を選択

・アカウント名に適当な名前を入力する

・ウェブサイトの名前に開発中のシステム名等を入力する

この後、ウェブサイトのURL入力が必須なのですが、ドメインは発行していないし、何を入力すればよいのだろう、ということで

①localhost

②VagrantのプライベートIP

③hostsに設定したドメイン名(test.v1.dev)

hosts側の設定:(VagrantのプライベートIP) test.v1.dev

をそれぞれ試してみました。

 検証

①「URL の最後のトップレベル ドメイン名が無効です」エラーとなり、登録不可

②登録OKとなり、下記のようなトラッキングコードが払い出されるので、サイトに埋め込みます。

<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-XXXXXXXX-Y', 'auto');
  ga('send', 'pageview');

</script>

http://(VagrantのプライベートIP)のサイトにアクセスした後、Googleアナリティクスのレポートを開き、リアルタイム>サマリーを確認します。

アクティブユーザー数が1になっています。データの計測に成功したようです。

③②と同様に登録OKとなるのでトラッキングコードを埋め込んだ後、http://test.v1.devにアクセスします。

レポートを確認すると、アクティブユーザー数が増えています。こちらも成功したようです。

 さらに検証

ウェブサイトのURLって結局何でも良いのでは?と思ったので、

④適当なドメイン名(hoge.com)

も試してみました。

トラッキングコードを埋め込んだ後、http://(VagrantのプライベートIP)にアクセスし、レポートを確認すると、アクティブユーザー数が増えています。

つまり、計測に使用されるのはトラッキングコードのみで、ウェブサイトのURLは結局何でも良いようです。

 追記

Googleのドキュメントにこのような記述がありましたが、設定しなくてもアクセスされていること自体は確認できました。(細かい分析のためには必要なのかもしれません)

ローカルホストでのテスト

https://developers.google.com/analytics/devguides/collection/analyticsjs/advanced?hl=ja#localhost

apxsのオプション

0

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

OpenSSLをソースから入れ直した時に
Apacheのmod_ssl.soを更新しても
ライブラリ参照先が変わらない事象があったので
オプションなどをメモ。

環境

  • CentOS 5系
  • Apache 2系
  • OpenSSL 1.0.1系

前提

  • yumで入っていたOpenSSL0.9.8系を、
    ソースから入れたOpenSSL1.0.1系にバージョンアップする
  • Apache自体は再コンパイルせず、
    apxsでモジュールのみ再コンパイルする

OpenSSLをソースからインストールしましたが、
Apacheはyumで入れたOpenSSLを参照したままなので
手動で入れた方を参照するよう更新する必要があります。

今回はApache自体はそのままで、モジュールだけapxsでコンパイルし直します。

apxsとは

「APache eXtenSion tool」
Apacheの拡張モジュールをビルドしてインストールするためのツールです。
後から拡張モジュールを組み込んだり、
モジュールだけ再コンパイルして入れ直したりすることができます。
DSOサポートが有効になっている必要があります。

有効になっているかの確認方法↓

# httpd -l
Compiled in modules:
  core.c
  prefork.c
  http_core.c
  mod_so.c

→core.c、mod_so.cがあればOK

有効になっていない場合はApacheをオプションつけて再コンパイル。
yumの場合はhttpd-develパッケージに入ってます。

mod_ssl更新

今回はmod_sslを再コンパイルしたいので、
mod_ssl.cファイルを探して、apxsコマンドを実行します。

# locate mod_ssl.c

mod_ssl.cのあるディレクトリに移動後、

# apxs -c -i *.c -lssl -lcrypto -ldl -lz

-c オプション: コンパイルする
-i オプション: インストールする
-l オプション: 共有ライブラリを指定

共有ライブラリの参照先を確認。

# ldd mod_ssl.so

libssl.so、libcrypto.soが手動で入れたOpenSSLの場所を参照していればOKなのですが、
結果はyumで入れたOpenSSLが参照されたままです。

その場合は-Lオプションでライブラリパスを指定できます。

※OpenSSLが/opt/opensslにインストールされている場合

# apxs -c -i *.c -lssl -lcrypto -ldl -lz -L/opt/openssl/lib

-L オプション: ライブラリパスを指定

これで手動で入れたOpenSSLの方にリンクしてくれるようになりました。

apxsコマンドのオプション

共通オプション
-n modnameモジュール名を明示的に指定。-i, -gオプションと共にに使用。
-gオプションを指定する場合は必須。
-iオプション指定時にこのオプションの指定がない場合はファイル名から推測される。
クエリオプション
-q設定(構成)情報を取得する。パラメータで取得情報を指定できる。
設定オプション
-S name=value設定を変更する
テンプレート生成オプション
-gモジュールのテンプレート(雛形)を生成する。
-nオプションの指定によってmod_○○.cというソースファイル、Mikefile等が生成される。
DSOコンパイルオプション
-cコンパイルする。
-oオプションがない場合は、通常ファイル名から推測されたmod_○○.soというモジュールが出力される。
-o dsofile作成されるモジュールのファイル名を明示的に指定
-D name=value設定オプションをコンパイル時に直接指定
-I incdirコンパイル時に直接指定したいインクルードディレクトリがあれば指定
-L libdirコンパイル時に直接指定したいライブラリパスがあれば指定
-l libnameコンパイル時に直接指定したいライブラリがあれば指定
-Wc, compiler-flagsコンパイラフラグを指定
-Wl, linker-flagsリンカフラグを指定
DSOのインストールと設定オプション
-iインストールする
-ahttpd.confにLoadModule行を追加して有効化する
-A-aオプション同様、httpd.confにLoadModule行を追加するが
有効化はしない(コメントアウトした状態で追加される)
-eモジュールはインストールせず、httpd.confのみ編集する

-aオプションは、
対象モジュールのLoadModule行が既にある場合に指定すると、
重複してしまい、apachectl configtestは通っても
エラーでApacheが起動しないので注意が必要です。

かなりざっくり略したので、詳細はman apsxで確認を。

Google APIの使い方について

0

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

GoogleのAPIを使用する方法について

 Projectの作成

Project作成

Google Developers Console(https://code.google.com/apis/console/)で新しいプロジェクトを作成します。

APIの有効化

API一覧から使用するAPIを選択し有効化(statusをEnable)します。

 トークンの取得

メールアドレス登録

Credentials(サイドメニュー) → OAuth consent screen(メイン画面タブ) から、Eメールアドレス(Email address)とProduct name shown to users(適当な文字列を入力)を登録します。

クライアントIDの発行

Credentials(サイドメニュー) → Credentials(メイン画面タブ)の

Create credentialsから「OAuth Client ID」を選択後、アプリケーションの種類を選択(Other)してクライアントIDを発行します。

登録が完了すると、画面にClient ID, Client Secretが表示されます(2016/07現在、Redirect URIsは表示されなくなった: http://localhost)

Authorization Codeを取得

ブラウザ上で以下のURLを入力します。リダイレクトURIとクライアントIDは上記で取得したものを入力します。

https://accounts.google.com/o/oauth2/auth?
scope=https://www.googleapis.com/auth/androidpublisher
&response_type=code
&access_type=offline
&redirect_uri=<redirect uri>
&client_id=<client id>

「<product name shown to usersで入力した文字列>が次の許可をリクエストしています」

と画面に表示されるので、「許可」ボタン(以前は承認するだったので名前は変わる可能性あり)を押下します。

ボタンを押した後リダイレクト先で、ブラウザのアドレスバーを確認します。

code=以降にAuthorization Code が入っています。

http://localhost/?code=<authorizationcode>

アクセストークンの取得

アクセストークンを取得するために、Authorization Code, Client ID, Client Secret, Redirect URI をPOST でリクエストを送ります。

curl -v -X POST 'https://accounts.google.com/o/oauth2/token' 
-d 'grant_type=authorization_code
&code=< Authorization Code >
&client_id=< Client ID >
&client_secret=< Client Secret >
&redirect_uri=< Redirect URI >'

レスポンスとして、アクセストークンとリフレッシュトークンが帰ってきます。

{
"access_token" : " アクセストークン",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "リフレッシュトークン"
}

 サーバ側設定

Gem

google API Client のGemを使用

https://github.com/google/google-api-ruby-client

使い方

require 'google/api_client'

# 初期化
client = Google::APIClient.new(
  auto_refresh_token:  true,
  application_name:    xxx,   # アプリケーション名やバージョン名を
  application_version: xxx    # 指定する場合は初期化時に入力
)

# 認証情報設定
client.authorization.client_id      = <取得したクライアントID>
client.authorization.client_secret  = <取得したクライアントシークレット>
# リフレッシュトークンにより, アクセストークンは都度取得する
client.authorization.refresh_token  = <取得したリフレッシュトークン>

# 使用するAPIとバージョンを指定
api_publisher = client.discovered_api("hogeAPI", "v1.1")

# API呼び出し
client.authorization.fetch_access_token!

response = client.execute(
  api_method: <api のメソッドを指定>,
  # パラメータを渡す場合はhashで指定
  parameters: {
    "xxx" => xxx,
    "yyy" => xxx,
    "zzz" => xxx
  }
)

responseにAPIのレスポンスが格納されます。

実行すると自分の内容を出力するシェルスクリプト

0

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

bash 上で自分自身の内容を出力するスクリプトの作成です。 cat コマンドの応用が面白いと思ったので紹介します。

 動機

パスワードのヒントやそこそこ頻繁に使う長めのコマンドをメモしておいてターミナル上で簡単に表示できるようにしておきたい。

echo "Qu'est-ce que c'est?"

 cat (基本)

テキストファイルの出力には cat コマンドを使用します。

echo "Je suis japonais." > sample.txt
	cat sample.txt

試しに自分を出力するシェルスクリプト

cat << EOF > sample.sh
	#!/bin/bash
	
	cat \$0
	
	# Nach dem Sinn von Sein soll die Frage gestellt werden.
	EOF
	chmod u+x sample.sh
	./sample.sh

 cat (応用)

# を不要にしたり、短くしたりできないか

例えば shebang に cat を使うとか。

cat << EOF > .1
	#!/bin/cat
	
	Veni, vidi, vici.
	
	γνῶθι σεαυτόν
	
	北 冥 有 魚 其 名 為 鯤
	
	EOF
	chmod u+x .1
	./.1

できた。PATHを追加すればファイル名だけで表示可能。名付けて猫スクリプト

curl でファイルを送る

0

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

http アクセスを行うコマンドラインツールは telnet, wget, lynx, w3m などあるがリクエスト結果をそのまま標準出力したい場合は curl コマンドが便利かと思っている。ファイルを POST するのも簡単だったので備忘の為、記載する。

 通常の使い方(bash上)

curl http://host/path/file.ext

※ ポストパラメータを渡すときは -F オプションを使う

e.g.
 のようなフォームで送るパラメータ。 
curl -F "param_name=param_value" curl http://host/path/file.ext

 ファイルを送るとき

e.g.
 のようなフォームで送るパラメータ。
curl -F "param_file=@file_path" curl http://host/path/file.ext

簡単でした。@マークをつけてファイルパスを指定するだけ。

 Appendix

get パラメータを送るときの注意

? や & は bash 上で特殊文字として処理されてしまうので URL ごと引用符で囲んでしまいましょう。

curl "http://host/path/file.ext?a=1&b=2&c=3"

よく使うオプション

  • -H ヘッダーを設定する。下記では名前解決できないけれど名前バーチャルホストを使用しているサーバへアクセスするときの確認に便利
  • -b 送信するクッキーファイルを指定
  • -c 受信するキッキーを保存するファイルを指定
  • -A ユーザエージェントの書き換え:iphoneやandroidやその他で出力が異なる場合の確認に便利
  • -v リクエストヘッダやレスポンスヘッダを表示
curl -v -H Host:virtual_host_name http://127.0.0.1/ -b ck0.txt -c ck1.txt -A "oreore_ua"

datetimepickerでの、あり得ない日付の入力制御の覚え書き

0

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

railsのビューで、フォームを使って日付を入力させたい時、

datetimepickerを使っていました。

datetimepickerはJSでテキストフィールドに付加する事で、カレンダー表示で日付・時間を選択させる事のできる便利なプラグインです。

ただ、テキストエリアに追加するので、ユーザーがテキストフィールドに直接日付を入力する事も出来てしまいます。

それ自体は別に問題ない事ですが、日付じゃないテキストや、あり得ない日付を入力されてしまう場合もあります。

日付じゃないテキストについては、datetimepickerが勝手に判断してテキストフィールドの中を空に置き換えてくれるのですが、

あり得ない日付に関しては、

「2000-04-31」-> 「2000-05-01」に変換してくれる

「2000-05-32」-> 変換してくれない!

となるので、フォームでもらった値を、

モデルインスタンスのDateTime型のカラムに代入しようとするとエラーを吐きます。

@model = Model.new(date: param[:model][:date])
 -> ArgumentError

どうやら31日までは,datetimepicker側で勝手に判断して変換してくれるようですが、

32日を超えると「ありえない日付」となり、変換はしてくれないようです。

これでは困るので、色々と解消しようとした顛末です。

 1. validationで弾けないか?

モデルにvalidateを設置して、フォームを送ったら「不正な値です」などのアラートを表示させたいと思いましたが、

よくよく考えると、validate発火前の、インスタンスへの代入時点でエラーになっているので、ちょっと厳しそうです。

コントローラの方でチェックするのも考えましたが、フォームを使うコントローラ全てにチェックを入れないといけなかったりするので、

あまり良くなさそうです。

 2. JSで弾く(onBlur編)

そもそもそのような入力が出来なければ良い話なので、JSで入力制御を入れる事にしました。

ちなみに、datetimepicker導入部のJSはこんな感じ。

$('.date_text_field').datetimepicker({
  format: 'YYYY-MM-DD',
  language: 'ja'
});

今回は日付だけ取りたいので、時間までは取らないようにしています。

このままだと入力制御がかかってないので、onBlurのイベントハンドラを使ってみます。

$('.date_text_field').datetimepicker({
  format: 'YYYY-MM-DD',
  language: 'ja'
});

$('.date_text_field').onBlur = function(){
  if ($(this).val() != '') {
	  var inputDate = new Date($(this).val());
	  if (isNaN(inputDate.getTime())) {
	    $(this).val('');
	  }
  }	
}

「isNaN(inputDate.getTime())」でテキストフィールドに入力された値が日付として正当か判断しています。

これでテキストフィールドに「2000-03-34」のようなおかしい日付を入力して、フォーム送信ボタンを押すと・・・・

テキストフィールドの中身が空になりました!

・・・しかし、onBlurを使っているので、テキストフィールドからフォーカスが外れれば空になってくれるのですが、

テキストフィールドに入力した状態で、エンターキーを押してそのままフォーム送信したりすると、、

フォーカスは外れないので、そのまま値が送られてしまい、やはりArgumentErrorになってしまいました。

 3. JSで弾く(onsubmit編)

ならば、フォーム全体がsubmitされたタイミングで入力判定すれば良いじゃないか!

という訳で、フォーム全体のイベント監視をさせるようにしてみます。

$('.date_text_field').datetimepicker({
  format: 'YYYY-MM-DD',
  language: 'ja'
});

$('form').on('submit', function(){
  picker();
 });

function picker(){
  $('.date_text_field').each(function(){
    if ($(this).val() != '') {
      var inputDate = new Date($(this).val());
      if (isNaN(inputDate.getTime())) {
        $(this).val('');
      }
    }
  });
}

formタグを監視するようにしてみました。

フォームがsubmitされると、date_text_fieldクラスを探し出し、日付として不正の場合値を空にします。

これで再度日付入力用のテキストフィールドに「2000-03-34」を入力してフォーム送信・・・

-> 送信直前にフォームの内容が空になりました!

 4. JSで弾く(解決編)

上記の方法で良いかと思ったのですが、

一画面に複数formタグがあったときは、そもそもformにJS監視させたくないときは?などの疑問が残ります。

そんな中、とてもスマートな解決法を教えて頂きました。

$('.picker_date').datetimepicker({
  format: 'YYYY-MM-DD',
  language: 'ja'
}).on('dp.error', function(e) {
  $(e.target).val('');
});

これだけです。formに対してのイベントリスナーもいりません。

dp.errorイベントを拾うことで、入力された値に不整合があると、値を空にすることが出来ます。

フォーム送信時だけでなく、テキストフィールドからフォーカスが移ったときにも評価が走ります。

ということで無事、datetimepickerへの入力制御を入れる事が出来ました!

便利なBootstrapデザイン

0

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

rickNo40です。
管理画面デザインをデザイナーが作ることはあまりないので、各ブラウザの調整など苦労したりします。
そこで、簡単に綺麗な管理画面が作成できるのがBootstrapです。
少々触る機会があったのでよく使ったデザインを少しだけ紹介下記全てクラス名

「col-md-?」
?部分は1~12の数字になります。
これは、1つのブロックを12分割し指定した分割分の領域を使用します。
入力フォームの幅を調整したり、
1行に幾つか要素を置くときに2,4,2,4で分割したりと便利です。

「text-left,text-center,text-right」
左寄せ・中央寄せ・右寄せですね。
使いたい時に、あぁまたcss設定しなきゃなんてならず、class名指定するだけなので楽です。

「table」
テーブルの基本デザイン
管理画面の大抵の画面がこれを使用して作ればいいです。

「table-striped」
テーブルで1行毎に色を変えてくれます。
縦結合する場合はだめですが、一覧表示するときは良い感じです。

「table-bordered」
テーブルの枠を表示します。
線があると無いとではやっぱり引き締まり具合が違います。
提供する管理画面なんかだったらborderはつけたが方がいいかと自分は思います。

「table-condensed」
テーブルの余白を縮めます
bootstarp基本的に余白多いんですよね。
1画面に収める量を増やしたい場合は、つけたほうがいいです。

「form-group,form-control」
入力フォーム系にはとりあえず付けておけばいいかと

「input-groupで囲んでinput-group-addon」
入力フォームの前や後ろに単位などをつけたりできます。
普通に書くと入力フォームと高さが微妙に違ってたりなんてことがあるので結構便利です。

と、こんな感じでルールが決まっているとそれを設定するだけなのでとても楽です。
Bootstrapでつくったからといって必ず綺麗になるわけでもありませんが、
少し試してみるのもいいかと思います。

AtomをEclipse風にカスタマイズ【パッケージ編】

0

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

無料のWeb開発向けテキストエディタ「Atom」を、Eclipse風にカスタマイズする方法をご紹介します。

今回はパッケージ編です。

※「設定・使い方編」と「パッケージ編」の2部構成

※注)以下はMacの設定となります。

 キーバインドをEclipse風にする

eclipse-keybindings

このパッケージはその名の通り、AtomのキーバインドをEclipseに近づけてくれます。

私はEclipseでよく以下のショートカットを使用しますが、もちろんこれらもそのまま使えます。

・全文検索:control + H

・ファイル検索:command + shift + R

 ファイルツリーに拡張子毎のアイコンを表示

file-icons

Eclipseだとデフォルトでファイルツリー上のファイル名の横に拡張子毎のアイコンが表示されていて、見栄えがよいです。

これを実現するのがこちらのパッケージ。

 メソッドツリーを表示

symbols-tree-view

サイドバーにメソッドの一覧を表示してくれるパッケージです。

コードが長いクラスを読む際に便利です。

 日本語化

japanese-menu

好みの問題ですが、Eclipse使ってる方はPleiadesで日本語化されている方が多いと思うので、こちらも入れておくとEclipseに一歩近づく(?)

 ツールバー

tool-bar

tool-bar-main

ツールバーが表示されるようにするパッケージです。

tool-barが本体ですが、本体だけだと自分でツールバーの内容を設定しないといけません。

tool-bar-mainを入れるとよく使いそうなツールバーを自動で設定してくれます。

こちらのパッケージもEclipseに近づけることがメインで実用性は低め・・。

また、デフォルトだとツールバーのアイコンが大きすぎるので、パッケージ側の設定で小さくします。

Atom->環境設定->パッケージ->tool-bar->設定(※設定が表示されていない場合はリスト自体をクリックすると表示されます)->Settings->

 icon Size:16px

 ダブルクリックした単語をハイライト

highlight-selected

Eclipseでも地味に便利なこの機能。単語をダブルクリックすると同じ名前の単語をハイライト表示してくれます。

ただ、背景が白のテーマにしている場合、どこがハイライトされているか分かり辛いため、こちらも設定を変更します。

Atom->環境設定->パッケージ->tool-bar->設定->Settings->

 ■Highlight Background

 ■Light Theme

設定・使い方編へ

http://doruby.kbmj.com/oneafter999_on_rails/20160516/Atom_Eclipse_

Docker を試してみる(2.5)〜Sentryを試す

0

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

今回はちょっと脱線して SentryというサービスをDocker上で実行してみます。

なお、Sentryはアプリケーションのログを収集して見やすくしてくれるサービスです。

https://getsentry.com/welcome/

SaaS型とオンプレ型が無償で提供されています。

sentry のオフィシャルイメージが用意されていますので、そちらを使います。

https://hub.docker.com/_/sentry/

基本的にこの手順に従っていくだけです。

事前準備: redisとPostgreSQLを起動

これもコンテナで起動します。

$ docker run -d --name sentry-redis redis
$ docker run -d --name sentry-postgres -e POSTGRES_PASSWORD=sentry -e POSTGRES_USER=sentry postgres

シークレットキーの作成

シークレットキーを出力します。

コンテナの起動時に使いますので覚えておいてください。

$ docker run --rm sentry generate-secret-key
hogehogesecretkey

データベースの作成

$ docker run -it --rm -e SENTRY_SECRET_KEY='hogehogesecretkey' --link sentry-postgres:postgres --link sentry-redis:redis sentry upgrade

途中で「ユーザを作るか?」ときかれますので、作っておきましょ。

linkオプションについて

docker run コマンドで –link というオプションが使われています。

これはコンテナ同士を通信させる簡単な方法です。

リンクしたコンテナの情報(IPなど)を共有して参照できるようにします。 –link コンテナ名(:エイリアス) で指定します。

sentryのコンテナ中でエイリアス(postresやredis)を使って参照(REDIS_PORT_6379_TCP_ADDRなど) しているので、上記の通りに指定しないと動きません。

サーバの起動

$ docker run -d -p 9000:9000 --name my-sentry -e SENTRY_SECRET_KEY='hogehogesecretkey' --link sentry-redis:redis --link sentry-postgres:postgres sentry

ホストの9000版アドレスにポートフォワードしてるので、http://localhost:9000 や http://192.168.33.11:9000 のようにしてブラウザから確認できます。

ワーカーの起動

デフォルトの設定で、workerのコンテナも必要なようなので起動しておきます。

$ docker run -d –name sentry-celery-beat -e SENTRY_SECRET_KEY=’hogehogesecretkey’ –link sentry-postgres:postgres –link sentry-redis:redis sentry celery beat $ docker run -d –name sentry-celery1 -e SENTRY_SECRET_KEY=’hogehogesecretkey’ –link sentry-postgres:postgres –link sentry-redis:redis sentry celery worker

最近人気な記事