読者です 読者をやめる 読者になる 読者になる

技術部

プログラミングのことが中心

Rails5でのモデルのファイルの整理

1対1リレーション

どうしてもカラム数が増えてくるとテーブルを分たりすることになる。また、頻繁に使用しない情報などもテーブル分けて保存したりする。

そうするとどうしてもmodel数が増えたりして管理するのが難しくなる。 そこで今回配下のようにまとめた。

userモデルとuser_profileモデルとする。 UserとUserProfile の関係は1対1の関係

migrateファイル

xxxx_create_user.rbは普通にいつも通りカラム等を記述する

xxxx_create_user_profile.rb

class CreateWorkerProfiles < ActiveRecord::Migration[5.0]
  def change
    create_table :worker_profiles, id: false do |t|
      t.integer :id, null: false
    end
    add_index :worker_profiles, :id, unique: true
  end
end

migrateファイルは普段通りにprimary_keyを設定するようにする。

model/usersディレクトリ作成

model配下にuser.rbとuser_profile.rbのふたつのファイルを以下のように配置する

model/users/profile.rb
model/user.rb

に分ける。

profile.rbの中身

module Users
  class Profile < ApplicationRecord
    self.table_name = 'user_profiles'
    self.primary_key = :id
    belongs_to :user, foreign_key: 'id'

    before_create { self.id = self.user.id }
  end
end

profile.rbの中身は上記ようにする。 ここでのミソは以下。

self.table_name = 'user_profiles'

というコードが必要となってくる。 あとのコードは1対1リレーションで主キーをuserテーブルの外部キーにするためのコード

Userモデルのリレーション

class User < ActiveRecord::Base
  has_one :profile, dependent: :destroy, foreign_key: 'id', class_name: 'Users::Profile'
end

ここで重要なのが、class_name。これを指定する必要がある。

その他テストファイル等

rspecやfactory_girlなども上記のよに

models/users/profile.spec

のようにしてあげる。

ファイルの中身は

RSpec.describe Users::Profile, type: :model do

と修正する。

以上で1対1のリレーションとファイルの整理。

これの何が利点なのか、プロジェクト膨大になってきて、UserだけでなくAdminのProfileが必要だとかなって来た時に うまく整理できる。

MySQLのストレージんエンジン

ストレージエンジン(データベースエンジン)

データベース管理システム(DBMS)がデータベースに対してデータの生成、読み取り、更新及び削除する機能のコンポーネント

MySQLのデフォルトストレージエンジンはinnoDB

ストレージエンジンの役割

ストレージエンジンの動作

  1. データベースエンジンがクライアントからSQL文を受け取ると、「“SELECT文”なのか“UPDATE文”なのか、どんな条件式がついているのか」などを把握するためにまずそのSQL文の解釈を行います。これをSQL文のパースと呼びます。
  2. 次にデータの処理方法を決める。プランナやオプティマイザと呼ぶ機能がこの仕事を行います。
  3. データの処理方法が決まると、はじめて実データへのアクセス処理が開始。実データがどのような形式で、ディスク上にどのように格納されているかといった情報が必要になる。ここが、ストレージエンジン部にになる

ストレージエンジンはテーブル単位

MySQLのストレージエンジンは、テーブル単位で指定することが可能。具体的には、CREATE TABLE文にてテーブルを作成する時にENGINE句にて、使用したいストレージエンジン名を指定する。

InnoDBの8KBの壁

デフォルトのMySQLでは、InnoDBの1行はデータ量8KB以下にしなければならない

8KBは何処から出てきた数値!?!?

ページサイズの半分。InnoDBではデフォルトのページサイズが16KBになっていて、その半分だから8KB>

  • ページとは?
InnoDBがディスク (データファイル) とメモリー (バッファープール) 間で一度に転送するデータ量を表す単位。

参考資料

問題と原因

問題

InnoDBでは8KBを超えた行を操作するとエラーになる

原因

可変長(text,varchar)の文字列型に値を入れると先頭768バイトだけローカルに保持して残りは外部のページに保持する。

参考資料

計算してみると?

8000バイト÷768バイト=約10.42

と以上から、可変長のカラムのうち11カラム以上に値が入ると8KBを越える。。。。。

対応方法

  • ROW_FORMATをDYNAMICに変更する。。。

    defaultでは、compact

ROW_FORMAT=DYNAMICを利用するにはInnoDB自体のファイルフォーマットをBarracudaに設定する必要があるので注意

  • innoDBinnodb_file_formatを AntelopからBarracudaへと変更する。。。

    ファイルフォーマットをBarracudaにするにはmy.cnfの設定を変更し、MySQLを再起動

ちなみに。。。

Rails(ActiveRecord)とMySQLでutf8mb4を扱う際にも上記のような設定を行うことで可能となる。

Gitのインストール

mac環境でのインストールについて

Homebrewのインストール

まずはhomebrewがインストールされていない場合はインストールする。

Homebrewとは?

Mac用のパッケージマネージャー
簡単に言うとAppStoreみたいにアプリケーションをインストールするためのもの

早速インストール

前提としてxcodeがインストールされていること

Homebrewをインストールするにはxcodeというツールが必要。
なので、イストールしてない人はAppStoreからインストールしてください。

もう一つ事前準備として以下のコマンドを入力 homebrewを使用する際に意識することはない。
まー必要なんだ程度で押さえておいてください。

xcode-select --install
公式ホームページからインストールコマンドを取得

HomebrewーOS Xようのパッケージマネージャー

*以下のコマンドは自分がインストールした時のコマンドなので、公式ホームページから取得したほうが確実

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
インストールしたら以下のコマンドでインストールされているかを確認する
brew -v
=> Homebrew 0.9.9

インストールがうまくいっていない場合エラーが出ます

一応エラー確認として以下のコマンドも入力
brew doctor

Gitインストール

前置きが長くなりましたが、題材でもある、Git のインストールbrewで行う
以下のコマンドを入力

brew install git

次にインストールされているか確認する

git -- version
=> git version 2.4.5

以上でgitのインストールの流れです。

gitの設定

gitの公式サイトでの設定を見ていただくのが一番わかりやすいとおもうので、こちらのサイト見ながら設定を行ってください。 Git のカスタマイズ - Git の設定

まーそこまで難しいことではないが、誰かの役に立てればということでブログを作成しました。

おそらくエラーなどが出る場合などがあると思いますが、その人の環境によってかわってくるとおもうので、

その都度自分で調べてみてください。

以上です。
実際には役に立ったでしょうか?
役に立てていれば幸いです。

最後まで見ていただきありがとうございます。

Gitの操作

Gitとは?

分散型バージョン管理システム

一つのファイルやファイルの集合に対して、時間とともに加えられていく変更を記録するシステム

バージョン管理システム導入メリット

ファイルを以前の状態に戻したり、過去の履歴を見直したり、誰が修正を行ったかの確認ができる。

Gitの操作

今回のブログでは、自分のgitに対しての理解の整理と初心者が簡単にgitに慣れるために覚えておくべきことを目標としている。

Gitリポジトリの取得

りぽじとりってなんだ?

リポジトリとは、ファイルやディレクトリの状態を記録する場所。保存された状態は、内容の変更履歴として格納されている。変更履歴を管理したいディレクトリをリポジトリの管理下に置くことで、そのディレクトリ内のファイルやディレクトリの変更履歴を記録することができる。

git ini

バージョン管理を開始することができるようになる

git clone

既存のGitリポジトリをコピーし、途中からでも開発に参加し、バージョン管理ができるようになる

branch操作

ブランチとは?

作業の履歴を分岐し、一作業ごとに記録としていくためのもの
分岐したブランチは、他のブランチに影響しない

統合ブランチとトピックブランチ

統合ブランチ

トピックブランチの分岐元となり、併合先のブランチのことで、このブランチを本番環境にデプロイする。
例)master/developが統合ブランチの役割

トピックブランチ

一つのトピックに集中して、他の作業は一切行わない、機能追加や修正作業ようブランチのこと。
トピックブランチは統合ブランチから分岐し、作業終了後統合ブランチへ取り込む。

ブランチの分岐

  • ブランチの作成と切り替え
git checkout -b feature-A

このコマンド何をしているのかというと、ブランチを作成し、作成したブランチに移動するのを同時に行った。

以下のコマンドと同じこととなる

git branch feature-A
> ブランチ作成

git checkout feature-A
> ブランチ移動

このブランチを作成し、ブランチに移動することこそが、作業履歴の分岐である。

ブランチの統合

ブランチを統合ブランチからトピックブランチを作成し、分岐した。修正、機能追加をしたブランチをまた、トピックブランチに統合する必要がある。

マージ

git checkout master
> 統合ブランチへ移動

git merge feature-A
> 統合ブランチへ修正ブランチをマージ(統合)

以上でgit branchについて。。。

gitで大切なファイル保存領域と操作

f:id:tun83:20160724144504p:plain

ファイル領域<インデックス>へファイルを追加

実行コマンド

git add <filename>

修正ファイルを管理対象とするために、git addでインデクス領域へファイルを登録 f:id:tun83:20160724144931p:plain

リポジトリの歴史を記録

実行コマンド

git commit -m 'message'

インデックス領域(ステージング)に保存されているファイル、作業記録を git commitでリポジトリの歴史として、記録する。 f:id:tun83:20160724145119p:plain

変更履歴をリモート上で共有

実行コマンド

git push origin branch_name

originとはリモートりポジトリの場所(URL)の別名のこと

ローカルリポジトリにある、変更履歴を複数人に共有するために、git push でローカルリポジトリ何の変更履歴をリモートリポジトリへアップロード f:id:tun83:20160724145448p:plain

最新の更新履歴のダウンロード

実行コマンド

git checkout master
> 統合ブランチに移動

git pull
> 最新の更新履歴のダウンロード

リポジトリの状態確認

実行コマンド

git status
> リポジトリの状態が表示される

git statusコマンドはGitリポジトリの状態を表示

差分確認

実行コマンド

git diff

git diffコマンドは、ワーキングツリーと最新コミット間の差分を確認する

プルリクエストベース開発作業

プルリクエストとは簡単にいうとコードレビューをしてもらうために、問いかけるような機能がある。(Github or Bitbucket etc)

git branch 
> 今現在のブランチがmasterであるかを確認。そうでない場合はmasterへ移動

git checkout -b feature-A(branch name)
> ブランチの作成と移動

> 何か機能の追加や修正を行う

git status 
> リポジトリの状態を確認

git diff
> 修正の差分を確認=>変な修正は入っていないかを見る

git add <修正filename>
> ファイル領域<インデックス>へファイルを追加

git commit -m 'add function'
> リポジトリの歴史を記録

git status
> リポジトリの状態を確認
> On branch second
nothing to commit, working directory clean
うまくいけばこのようなメッセージが返ってくるはず

git push origin fixes-A(branch name)
> 変更履歴をリモート上で共有

> Github or bitbucket上でpullrequestをだす。
> pullrequestでレビューがオーケーならばそこでマージ=>ブランチの統合

git checkout master
> 統合ブランチへ移動

git pull
> 最新の更新履歴のダウンロード

以上が一般的なGithub or bitbucketでのプルリクエスとベースでの開発の流れである。

だいたいこれで、ごくごく一般的なgitの使い方を説明した。
おそらく、これくらい知っていればなんとかはなると思う。(コンフリクトなどがおき、複雑になってくるとまた違ったコマンドを覚える必要がある)

今回のブログでは、自分のgitに対しての理解の整理と初心者が簡単にgitに慣れるために覚えておくべきことを目標としている。

なので、そこまで深いおいはしていない。

まずは、少しいじってみてどんな感じなのかのイメージがつかめることができたらそれでいいのではないかを思うからである。

何かわからないこと、ここは違うだろーなどがありましたら、コメントでもなんでもください。

最後までお読みいただきありがとうございます。

ちなみに僕が読んだ本

GitHub実践入門 ~Pull Requestによる開発の変革 (WEB+DB PRESS plus)

GitHub実践入門 ~Pull Requestによる開発の変革 (WEB+DB PRESS plus)

Rubyにおけるオブジェクト指向

rubyオブジェクト指向について自分なりの解釈でまとめてみた。

Ruby OOP

Object Oriented Programming

対象(オブジェクト)そのものに重点を置き、対象の振る舞いや操作が対象の属性として備わるという考え方に基づいてプログラミングすること。プログラムの再利用が容易になり、ソフトウェアの生産性を高めることができる。

RubyにおけるObject

  • 全てがオブジェクト

インスタンスオブジェクト(インスタンス/オブジェクト)

  • データを表現する基本的な単位とデータの処理の集まり

    各種クラスからnewすることでRuby実行空間に生み出されるデータ型

String.new  =>  " "

Stringクラス  文字列オブジェクト

クラスオブジェクト(クラス)

  • オブジェクトの種類を表すもの!!オブジェクトの雛形

    オブジェクトの振る舞いを決める!!

たい焼き

  • たい焼きを焼く時の型 => クラス
  • 出来上がったたい焼き => インスタンス

たい焼きの型(クラス)をもとにたい焼きというインスタンスが作られる。

クラスとインスタンス

Stringクラスという設計図からできたインスタンス、実体

'Hello World'

上記の'Hello World'という文字列は、String クラスという設計図からつくられた、インスタンス、文字列オブジェクト

オブジェクトとしてのクラス

クラスはオブジェクトの雛形であり、クラスはオブジェクトの振る舞いを決める

ここで話がおかしくなる。 クラス自体もオブジェクトであるということ!!!

オブジェクトには✖︎✖︎クラスというクラスから成り立つ=>その︎✖︎✖︎クラスにもClassクラスというクラスから成り立っている

* String.class => Class
* Hash.class => Class
* Array.class => Class
* Numeric.class => Class

要するに?

  • あらゆるクラスはClassという一つのクラスから作られる。
  • あらゆるクラスは、Classクラスのインスタンス、オブジェクトということ!!

継承

親クラス(スパークラス)から機能を受け継ぐ

  • 既存の機能はそのままで、新たな機能を追加したい時
  • 既存の機能に処理を追加し、拡張したい時

class Person
  def initialize(name)
    @name = name
  end

  def name
    @name
  end
end

class PersonCharacter < Person  # Personクラスのサブクラス(Personを継承している)
  def initialize(name, age, sex)
    super(name)
    @age = age
    @sex = sex
  end

  def age
   @age
  end

  def sex
    @sex
  end
end

me = PersonCharacter.new('tun', 25, 'man')
puts me.name #=>tun
puts me.age #=>25
puts me.sex #=>man

モジュールオブジェクト(モジュール)

  • クラスによく似たオブジェクト

    Module.class => Class

クラスとの相違点

  • モジュールはインスタンスを持つことができない
  • モジュールは継承できない=>Mix-in

Mix-in

モジュールによる機能追加 => モジュールをクラスに混ぜ合わせるMix-in

 module MyModule
  # 共通機能、処理
end

class MyClass
  include MyModule # =>これがMix-inによるモジュール機能追加
  # MyClassの固

module Behavior
  def self.description
    description =  "I'm a Behavior Module"
  end

  def sleep
    sleep =  "I'm sleeping"
  end

  def eat
    eat = "I'm eating"
  end
end

class Person
  def initialize(name)
    @name = name
  end

  def name
    @name
  end
end

class PersonCharacter < Person # Personクラスのサブクラス
  include Behavior
  def initialize(name, age, sex)
    super(name)
    @age = age
    @sex = sex
  end

  def age
   @age
  end

  def sex
    @sex
  end
end

me = PersonCharacter.new('龍頭', 22, 'man')
puts me.name #=>龍頭
puts me.age #=>22
puts me.sex #=>man
puts me.eat #=>I’m eating

この他にも?

rubyは全てがオブジェクト!!

例えば nil true falseなどもすべてがオブジェクトである。

一言でオブジェクト指向プログラミング

自分なりの解釈

オブジェクトという部品を組み合わせていくプログラミング手法

オブジェクト指向というのは概念的な話であるから、ひとそれぞれ受け止め方が変わってくるのかなーってかんじる。ひとまず自分のなかでのオブジェクト指向とはと聞かれるとこのように答える。

最後まで読んでいただきありがとうございます。 なにか間違っていることなどあればご指摘お願いいたします。

参考図書

Effective Ruby

Effective Ruby

AWSの勉強メモ

ELB(load-balancer)

  • 複数仮想サーバーを立てている際に、アクセス集中をその複数のサーバーに振り分けることで処理を振り分けている

EC2(仮想サーバー)

  • インスタンスを作成することで、仮想サーバーを使用可能となる

    1つのインスタンスに対して、一つの仮想サーバーとしての振る舞い

  • イメージ

    Virtual Box的なもの。。。

  • リージョンとは?

    地域に存在するデータセンター群のこと

  • アベイラビリティ

    それぞれのリージョンを分割

    耐障害性を高める概念

    あるリージョンの中のあるアベイラビリティゾーンを選ぶことで、選んだアベイラビリティゾーンが災害被害を受けた際でも、同じリージョンの違うアベイラビリティゾーンに移行することで耐障害性を高めている。

流れとしては、EC2にrailsアプリケーションを置くことで、実際にアプリケーションをウェブ上で動かすことができる。 データ処理などはリクエストが来た際にRDS(データベース)に投げかける

s3(ストレージ)

  • インターネット経由で利用可能なストレージサービス

  • 使用例

    • コンテンツ配信(html js css 画像ファイル)
    • ログデータ等の保存
  • オブジェクトとは

    S3に格納されるファイル

  • オブジェクトのコンテナ(保存場所)。すべてのオブジェクトはバケット内に格納される。

Cloud Front

  • DNSサーバー
  • 高速配信するために強くキャッシュを効かせるネットワーク構成
  • 静的コンテンツの高速配信

RDS(データベース)

  • データベース管理

IAM(Identity and Access Management)

  • ユーザー(開発者)に対して、AWSへのアクセスを制御するもの
  • あるユーザーに体して権限を限定することができる

IAMロール

  • 通常AWSリソースへのアクセス権のないユーザー、アプリケーションなどにアクセス権を与えることができる。

    • あるアプリケーションなどからAWSリソースへのアクセスする際にあるアプリケーションにフルアクセス権限を与えることであるアプリケーションからawsリソースへとアクセスすることができるようになる

デプロイ(踏み台)サーバによる

  • deploy用にのサーバーのこと

    プロダクション環境の各EC2インスタンスソースコードをデプロイする場合、デプロイ用のサーバを1台用意すると便利。踏み代用サーバと兼務しても良い。

この際に、プロダクション環境にある、EC2にはIAMロールから認証することでアクセス可能とする。

踏み台サーバーを使用すると何がいいか?

  • セキュリティの強化

    セキュリティ攻撃のステークホルダーをなるべくなくす

  • 踏み台サーバーによるデプロイをすることでELB(load-balancer)からどこに(EC2インスタンスの住所)デプロイするかの情報を受け取ることできる。

AMIは何をする?

AMI = Amazon Machine Image

EC2をパッケージ化した感じ?

VPCとは何か?どのような役割をしているのか?

VPC = Virtual Private Cloud

  • 実際にサーバー構築をする際にまずどんな役割のサーバーが必要かを検討する

    web(EC2やS3) DataBase など

そこで、インターネットから直接EC2にアクセスすることはできるが、DataBaseにはアクセスできないようにする際にゾーン分けをする。 ゾーン分けをすることで、アクセス権限などを容易にする。DBにアクセスできるのは、このゾーンにあるEC2インスタンスからのみだよーなどの権限を与えることで、セキュリティなどが強化される。

VPCというのは簡単に言うと、クラウド上でゾーン分けをすることができる。

なぜVPCを用いる?

  • セキュリティ

    • VPCを構築することで、サブネット単位・ホスト単位での柔軟なアクセス制御ができる
    • パブリック・プライベートサブネットの切り分けができる
  • ネットワーク

    • 固定のローカルIPを使える

静的コンテンツのみをサーバーに置く際はS3? EC2?

  • s3を使用した方が安全しかし、S3はストレージに特化しているため遅いという問題点がある
  • CDNを使うことで速度の改善ができる(Cloud Front)

結論から言うと、S3に起き、S3と共に、Cloud Frontを使用する。

CDN

CDN = Contents Delivery Network

役割
  • アクセス元からみて距離的に一番近い場所にあるサーバーを自動で選択してくれる

  • キャッシュサーバーによる高速化

    • キャッシュがある場合、ユーザーへレスポンスしてくれる
    • キャッシュがない場合、本来のWebサーバーへアクセス

補足

サーバーの速さを決める要素

  • CPU

    データ処理など行う。

    CPUが早いということは、処理速度が早いということ

  • メモリ

    CPUが処理を実行するための作業スペース

  • DISK

    データの保管庫。容量が多ければ多いほど、ファイル保存量も多くなる。

    HDD => ハードディスクの読み取り装置。

    • 容量が多い
    • データ通信速度が遅い

    SSD => フラッシュメモリを記憶装置としたストレージ。HDDと同じ接続インターフェースを備え、HDDの代替として利用できる

    • HDDよりもデータ通信速度が速い。
    • 容量が少ない

まだまだ理解度が弱いなーと自らが感じる

ひとまず勉強メモ

指摘箇所あれば都度お願いします。