TECH EXPERT 32日目

TECH::EXPERT

学んだことを実装に乗せていく。
知識だけだったものが形になるので楽しい反面、いろんなところでつまづく。
やっぱり実務が一番勉強になるなぁ。

今日で難所は終わったのでほぼクリアかな。
あとはサーバー周りの知識になるので後は詰め込むだけ。
特に考える工程はなさそうなので心配いらない。

ruby

引数

デフォルト引数

引数は左から順に読まれ、引数がなかった場合に=の右辺が代入される

hoge(fuga="fooo")

hoge  => "fooo"

可変長引数

*をつけると可変長な引数となる。要は配列で指定し放題。

def hoge(*fuga)
  put fuga
end
hoge("aaa","abb","abc")
=>  ["aaa","abb","abc"]

キーワード引数

引数をハッシュで宣言できる。
宣言順を考慮しなくて良いので扱いやすい反面、キーを入力しないといけないので面倒。

def self.piyo(name: 'satou', text: 'hello' )
  p "#{name}, #{text}"
end

繰り返し処理

.times

object.times {処理}

例
10.times {puts "aaa"}

0 〜(オブジェクト内の数値-1)まで繰り返す。

.upto / .downto

object.upto(max) {処理}
object.downto(max) {処理}

例
5.upto(10) {puts "aaa"}

(オブジェクト内の数値)〜maxまでの値まで繰り返す。
上の例の場合、5,6,7,8,9,10と6回繰り返す。

rails

where

複数条件検索

User.where(‘id = ? or name = ?‘, 5, ‘satou’)
User.where(‘id = ? and name = ?‘, 5, ‘satou’)

where.not

@users = User.where('name LIKE(?)', "%#{keyword}%").where.not(id: current_user.id)

API

自動更新

webAPI

json形式で情報をレスポンスするアクションはwebAPIと言われる。
railsではWebAPIにあたるアクションを書くコントローラのファイルは全てapiというディレクトリに置くルール。

コントローラにAPIフォルダを作成し、API化するコントローラのrbファイルを作成。

例
app/controllers/api/messages_controller.rb

同様にviewファイルもフォルダを作成してから作成

例
app/views/api/index.json.jbuilder

名前空間(namespace)

class Api::MessagesController < ApplicationController
  def index
  end
end

同名のコントローラ名を使いたい場合、コントローラ名の前に::をつけて別名を付与できる。
名前空間をつけることにより、同名であっても区別できる。

Api::MessagesControllerとする場合には、相当する位置にmessages_controller.rbファイルを置く必要がある。
つまり、controller/api/messages_controller.rbに置く。
名前空間を増やしてディレクトリを深くする場合には、ディレクトリにそった命名が必要。
controller/api/hoge/fuga/messages_controller.rbなら
Api::Hoge::Fuga::MessagesControllerと命名する。
でなければ404not foundとなる。

なお対応するviewファイルはそれより1段深い階層に設置する。
(コントローラの分だけ深くなる)
views/api/messages/index.json.jbuilder

resourcesでnamespaceのネスト

通常通りネストした場合と大きな変化はない。
単にネストの親のidの次にnamespace名を挟むだけ。

  resources :groups  do
    namespace :api do
      resources :messages
    end
  end
      group_api_messages GET    /groups/:group_id/api/messages(.:format)          api/messages#index
                         POST   /groups/:group_id/api/messages(.:format)          api/messages#create
   new_group_api_message GET    /groups/:group_id/api/messages/new(.:format)      api/messages#new
  edit_group_api_message GET    /groups/:group_id/api/messages/:id/edit(.:format) api/messages#edit
       group_api_message GET    /groups/:group_id/api/messages/:id(.:format)      api/messages#show
                         PATCH  /groups/:group_id/api/messages/:id(.:format)      api/messages#update
                         PUT    /groups/:group_id/api/messages/:id(.:format)      api/messages#update
                         DELETE /groups/:group_id/api/messages/:id(.:format)      api/messages#destroy

resourcesのオプション

formatオプションをつけるとアクセスした際のレスポンスを設定できる。

resources :messages,only: :index, defaults: { format: 'json' }

rake routesすると以下のように変化する。
api/messages#index {:format=>"json"}

jsonファイルの値の渡し方

以下のようにインスタンスを渡してまとめて定義することもできる。

json.(@message, :content, :image)

ajax

リダイレクトするパス

ajax関数のurlに何も指定しなかった場合、リクエストのURLは現在ブラウザに表示されているパスになる。
urlに文字列で値を指定すると、現在ブラウザに表示されているURLの後に繋がる形になる。

http://hogehoge.com/fugaの時
$.ajax{
  url: "hoge"
}
とすると
404 Not Found
へリダイレクトする。 $.ajax{ url: "/hoge" } とすると
404 Not Found
へリダイレクトする。

jQuery

.data()

引数なしの場合カスタムデータ属性を取得する。

$('p').data();

引数をつけた場合、該当するカスタムデータを取得する。

$('p').data('name');
↑
これはdata-nameの属性情報を取得する。

2つ引数をつけた場合、該当する属性に値を代入する。
属性がない場合には属性を付与する。(jQuery内部だけ有効)

.data( 属性名, 値 )
$('p').data('name', 'taro');

.data()と.attr()の違い

.attr()で情報を取得する場合は”data-”を省略できない。
また.data()に関しては取得した情報や代入した情報はjQuery内部でだけ扱われ(キャッシュされ)、htmlそのものへは影響しない。
一方、attr()で属性情報を変更した場合にはhtml自体が書き換えられる。

:last .last()

要素のうち、最後のものを取得する。

$('li:last')

以下も同様に使える。

$('li').last()

Java

文字連結

+を使う。array.joinは処理が重いので避けたほうが無難。

特定のページのみjavaを起動させる

if(document.URL.match(pattern)) {
}

HTML

カスタムデータ属性

dataから始まる文字列で自由に使って良い(命名してよい)属性。
jQueryではDOMに対しdataメソッドを使い取得できる。

data-名前=任値

HAML

カスタムデータ属性

%div{data-user_id=1}などと書くとSyntaxErrorになる。
ハイフンが使えないため、以下のようにハッシュネストにする。

{ data:{message_id: message.id} }

なお上記の場合、以下のように展開され、_がハイフンに変換されてしまう。
data-message-id="183"

rubyのシンボルに「-」を含めるには、ダブルクォートでくくる必要があるので上記のようなハッシュで変換してくれる仕様になっている。

正規表現

文字列で正規表現パターンを指定する。
エスケープ処理と混同しないため、\dなどの文字は\\dとバックスラッシュを2重にする。

var pattern = new RegExp("groups/\\d\\d/messages")

「*」「+」

*は直前の文字の0回以上の繰り返し
+は直前の文字の1回以上の繰り返し

IPアドレス

グローバルIPアドレス

WAN(Wide Area Network)

プライベートIPアドレス

LAN(Local Area Network)

– クラスA:10.0.0.0~10.255.255.255
– クラスB:172.16.0.0~172.31.255.255 
– クラスC:192.168.0.0~192.168.255.255

小規模ネットワークはクラスCを使う。
普通のルーターはクラスC

プライベートIPは192.168,x,y
xはルーターのメーカーを表し、yはそれぞれの機器に割り振られる。
そのため一つのルーターが割り振れる番号は256通り。

DNS(Domain Name System)

IPアドレスを文字列化する仕組み

digコマンド

ドメインからIPアドレスを取得する。
domain information groperの略。

WARNING: EDNS query returned status FORMERR - retry with '+noedns'

上記のようなwarningが出た場合、
 dig +noedns www.yahoo.co.jp
とnoednsをつけてdigすると動く。

ポート

0から65535まで使えう。
0から1023までの番号はよく使われるもので予約されていて自由に使えない。

HTTPとは

WEBページやページ内で必要なCSS, JavaScript、画像などのファイルをWEBサーバにリクエストするためのフォーマットのこと。

URL(Uniform Resource Locator)/URI(Uniform Resource Identifier)

telnet

インストール

brew telnet install

Linux

sudo, su

sudoは現在のユーザーのまま他のユーザーに成り代わってコマンドを実行できる。
sudoコマンドを使うためには、予めsudoが使える権限がそのユーザーに付与されている必要がある。

suは他のユーザーにログインし直す事ができる。
いつでも使えるが、ログインしようとしているユーザーのパスワードが必要。

パーミッション

読み込み(r)、書き込み(w)、実行(x)の権限
r=4、w=2、x=1 という数字が割り当てられている。
ls -l [権限を確認したいファイルのパス]で確認できる。

所有者・グループユーザー・一般ユーザーの順で表示される。
数字で755などと表示される。

chmod

アクセス権限を書き換える

chmod [権限の種類] [ファイル/フォルダ]
例
chmod 777 projects/project1

chown

ファイルやディレクトリの所有者を変更する

chown [所有者][ファイル/ディレクトリ]

パッケージ・マネージャ

yumコマンド

# パッケージをインストールする
$ yum install [ファイル名]

# システムにインストールされているパッケージをアップデートする
$ yum update

# パッケージをアンインストールする
$ yum remove [ファイル名]

# サーバーにあるパッケージを一覧する
$ yum lis

シェル

ユーザーの入力したコマンドを解釈するソフトウェアのこと

ls

listの略で、フォルダやファイルの一覧を表示する。

ディレクトリ

  • カレントディレクトリ(.)
  • 親ディレクトリ(..)
  • ホームディレクトリ(~)
  • ルートディレクトリ(/)

cp

copyの略

cp [コピー元] [コピー先]
cp test.rb test_copy.rb

mv

ファイルの移動およびリネーム

#ファイルの移動
mv [移動させたいもの] [移動先]

# 名前変更
mv [元のファイル名][新しいファイル名]

rm

ファイルを削除する

rm [削除したいファイル名]

mkdir

ディレクトリを作成する

mkdir [ディレクトリ名]

touch

指定したファイルが存在しない場合は空のファイルを新規に作成する。
指定されたファイルへのアクセス時刻と更新時刻を現在の時刻または任意の時刻に変更する。

 # 新規のファイルを作成する・アクセス時刻と更新時刻を現在の時刻に変更
touch [ファイル名]

#  sampleファイルのアクセス時刻や最終更新日時を21年10月11日22:00に変更
touch -t 2110112200 sample

cat

ファイルの内容を結合し、表示するコマンド。
concatnateの略

# ファイルの閲覧
cat [ファイル名]

# ファイルの結合
cat [ファイル1] [ファイル2]

tail

ファイルの終わり部分を表示する。
オプションをつけずに実行すると終わりから10行表示される。

tail -f error.log

-fオプションをつけると、エラーログが追加されるたびに自動で新しいエラーログを表示してくれる。

プロセスを確認

psコマンド

実行中のプロセスを表示。

-a自分以外のユーザーのプロセスも表示する。
-r実行中のプロセスのみを表示する。
-uユーザー名とプロセスが実行された時刻を表示する。
-aux実行中のすべてのプロセスに関してCPU使用率などの詳細な情報つきで表示する。

| (パイプ)処理

左辺が最初に実行され、右辺へ処理が移る。

ls | grep p

kill

プロセスを終了する。

kill [プロセスID]

vi

通常モード

コマンド説明
:w作成・編集したファイルを保存します。
:qviコマンドを終了します。
:q!編集した内容を保存しないでviコマンドを強制終了します。
:wq編集した内容を保存してviコマンドを強制終了します。

/ (検索)

/に続けて文字をうち、enterすると検索文字へ移動する。

u (アンドゥ)

インサートモード中の処理を1つずつundoできる。

i (インサートモード), ESC

SSH

Secure Shell。
リモートコンピュータと通信するためのプロトコル。
暗号化されるため、安全に通信できる。

秘密鍵と公開鍵

ssh-keygen -t rsa

上記を打てば秘密キーと公開キーを生成できる。

公開鍵は ~/.ssh/id_rsa.pub、秘密鍵は~/.ssh/id_rsaに保存される。

公開鍵でのログイン手順

~ $ cd .ssh # .sshディレクトリへ移動
.ssh $ ssh-keygen -t rsa  # 公開鍵と秘密鍵を作成

指示通りパスワードを入力

リモートサーバにローカル環境の公開鍵のファイル(id_rsa.pub)をコピーする

# .sshディレクトリにローカル環境の公開鍵のファイル(id_rsa.pub)をコピー
$ scp ~/.ssh/id_rsa.pub [ユーザー名]@ [IPアドレス]:~/.ssh
awsではpemでSSHできるため以下のようにするのが一般的。
$ ssh -i [ダウンロードした鍵の名前].pem ec2-user@[作成したEC2インスタンスと紐付けたElastic IP]

ローカル環境の公開鍵のファイル(id_rsa.pub)の中身をリモートサーバの公開鍵のファイル(~/.ssh/authorized_keys)に追記。

リモートサーバの公開鍵のファイル(~/.ssh/authorized_keys)を作成し、その中にローカル環境の公開鍵のファイル(id_rsa.pub)の中身を追記。
ローカル環境では、公開鍵はid_rsa.pubに保存しましたが、リモートサーバでは公開鍵は ~/.ssh/authorized_keysに保存する。

# リモートサーバにログイン
$ ssh [ユーザー名]@ [IPアドレス]

# .sshディレクトリへ移動
$ cd ~/.ssh  

# リモートサーバの公開鍵のファイル(~/.ssh/authorized_keys)を作成
touch .ssh/authorized_keys

# 公開鍵の中身を追記
$ cat ~/id_rsa.pub >> authorized_keys

scpコマンド

送信先のディレクトを指定してファイルを送る。

AWS

EC2(Elastic Computing Cloud)

Amazon EC2(仮想サーバ)、Amazon S3(クラウドストレージ)、Amazon RDS(データベース)

デプロイ

デプロイ(deploy)とは配置する、展開するの意。

疑問

hamlの変換のされ方の違い
属性と本文で扱いが違うのはなぜ?

%span.user-name{ data:{message_id: message.id}} message.user.name
<span class="user-name" data-message-id="183">message.user.name</span>

%span.user-name{ data:{message_id: message.id}}= message.user.name
<span class="user-name" data-message-id="183">fooo</span>

turbolinksで発火が持続する

$(document).on('turbolinks:load', function() {
  var pattern = new RegExp("groups/\\d\\d/messages")
  if(document.URL.match(pattern)) {
    setInterval(reloadMessages, 5000);
  }
}

turbolinksでページ遷移時にjavaが無効になるのを回避した。
が、url.matchが機能しなくなった。
厳密には初回アクセス、リロード時には動作するのだが、条件外のページ遷移時にif文が評価されない感じ。(評価しているけどtrueなのかもしれないが)

dig

+noednsオプションってなに?

コメント