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

zakihayaメモ

RubyとRailsのことが中心

has_manyな関連にbuildした後にsortを実行したい

[Rails] has_many through な関連をチェックボックスで操作するときに苦労した話 | ハレノヒブログ

こちらのページを参考に、WordPressのカテゴリー選択UIみたいのを作りました。
が、これだと選択されたカテゴリが上に来てしまってソート順が無効になってしまうので、何とかする方法。

普通にsort!使えばいいじゃない

ということで下のようにやってみる。

article.categorizations.sort! { |a, b| a.category_id <=> b.category_id }

すると、sort!なんて無いといわれる。なぜだ。。。

has_manyなアソシエーションで取得できるcollectionはArrayではない

クラス名::ActiveRecord_Associations_CollectionProxyというクラスらしい。
そしてこのクラスはsort!を持っていない。

よく見たら、article.categorizations.targetにも同じデータが入っているように見える。
そしてこいつのクラスはArray。

なので、こうしたらうまくいった。

article.categorizations.target.sort! { |a, b| a.category_id <=> b.category_id }

targetをいじっていいのか迷ったが、公開されてるプロパティなので大丈夫なんだろう。。。

AWS VPC内にRDSでDBを作成する

AWS VPCでセグメントを分けてサーバを管理する - zakihayaメモ
AWS VPC内にアプリケーションサーバを作成する - zakihayaメモ
の続きです。

DBを作成して、アプリケーションサーバから接続できることを確認します。

RDSからVPCを利用するための設定

1) AWSにログイン → RDSを選択

f:id:zakihaya:20140503184121p:plain

2) Subnet Groupsを選択 → Create DB Subnet Groupをクリック

f:id:zakihaya:20140503185606p:plain

3) Subnet Group名を入力し、private subnetを選択 → Addをクリックし、Yes, Createをクリック

f:id:zakihaya:20140503185958p:plain

RDSインスタンスの作成

1) AWSにログイン → RDSを選択

f:id:zakihaya:20140503184121p:plain

2) Launch a DB Instanceをクリック

f:id:zakihaya:20140503184218p:plain

3) MySQLを選択

f:id:zakihaya:20140503184320p:plain

4) Noを選択してNext Stepをクリック

f:id:zakihaya:20140503184450p:plain

Multi AZにする場合はここでYesを選択する

5) DBの情報、サイズ、ユーザー、パスワード等を入力する

f:id:zakihaya:20140503184837p:plain

6) VPC、DB Subnet Groupを選択してNext Stepを選択

f:id:zakihaya:20140504191313p:plain

7) バックアップの設定

f:id:zakihaya:20140504191409p:plain

8) 最後の確認ページでLaunch DB Instanceをクリック

接続確認

アプリケーションサーバから下のコマンドを実行

$ mysql -h testdb.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -u awsuser -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 5.6.13 MySQL Community Server (GPL)

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

AWS VPC内にアプリケーションサーバを作成する

AWS VPCでセグメントを分けてサーバを管理する - zakihayaメモ
の続きです。

VPCとサブネットを作成したので、public subnetにアプリケーションサーバを作成します。

EC2インスタンスの作成

1) AWSにログイン → EC2を選択

f:id:zakihaya:20140503180949p:plain

2) Launch Instanceをクリック

f:id:zakihaya:20140503181139p:plain

3) Amazon Linuxを選択

f:id:zakihaya:20140503181256p:plain

4) 今回はmicroインスタンスで作成するので、そのままインスタンスの設定画面へ

f:id:zakihaya:20140503181640p:plain

5) 作成したVPC、public subnetを選択し、Public IPにチェックを入れて、Review and Launchをクリック

f:id:zakihaya:20140503182623p:plain

6) 確認画面でLaunchをクリック

f:id:zakihaya:20140503183252p:plain

AWS VPCでセグメントを分けてサーバを管理する

VPCとは

Amazon Virtual Private Cloud(Amazon VPC)で、アマゾン ウェブ サービス(AWSクラウドの論理的に分離したセクションを確保し、ここで、お客様が定義する仮想ネットワークで AWS リソースを起動することができます。独自の IP アドレスレンジの選択、サブネットの作成、ルートテーブル、ネットワークゲートウェイの設定など、仮想ネットワーク環境を完全にコントロールできます。

AWSの中に専用のネットワークが作れるようなイメージです。

今回は下のような構成で構築します。

f:id:zakihaya:20140503162727p:plain

VPCを作成する

1) AWSにログインし、VPCを選択する

f:id:zakihaya:20140503163008p:plain

2) Your VPCsをクリック → Create VPCをクリック

f:id:zakihaya:20140503163704p:plain

ここにもともとあるVPCは消してはいけないそう。
EC2のインスタンス等を作成する時にVPCを指定しないと、このデフォルトVPCに作成される。

3) VPCの名前とネットワーク全体を表すアドレスを入力して、Yes, Createをクリック

f:id:zakihaya:20140503164325p:plain

TenancyはDefaultを選択しておく。
Dedicatedにすると1つの物理マシンを専有できるが、高いらしい。

サブネットを作成する

1) Subnetsを選択 → Create Subnetをクリック

f:id:zakihaya:20140503164827p:plain

2) public subnetの情報を入力して、Yes, Createをクリック

f:id:zakihaya:20140503165221p:plain

AZはどこでもOK

3) 同様にprivate subnetを作成する

f:id:zakihaya:20140503165600p:plain

Internet Gatewayを作成する

1) Internet Gatewaysを選択 → Create Internet Gatewayをクリック

f:id:zakihaya:20140503170027p:plain

2) 名前を入力して、Yes, Createをクリック

f:id:zakihaya:20140503172309p:plain

3) 作成したInternet Gatewayを選択して、Attach to VPCをクリック
  → ダイアログが開いたら、Yes, Attachをクリック

f:id:zakihaya:20140503172511p:plain

Route Tableを作成する

Route Tableについて

サブネット間、サブネットとインターネット間の仮想的なルーティングテーブルのようなイメージ。
デフォルトで作成されているRoute TableはVPC内の通信のみ可能になっているので、そのままprivate subnetに利用する。public subnet用にはインターネットにできるRoute Tableを作成する。

public subnet用Route Tableの作成

1) Route Tablesを選択 → Create Route Tableをクリック

f:id:zakihaya:20140503175203p:plain

2) 名前を入力、VPCを選択してYes, Createをクリック

f:id:zakihaya:20140503175333p:plain

3) 作成したVPCを選択して、Editをクリック

f:id:zakihaya:20140503175457p:plain

4) Destinationに0.0.0.0/0、TargetにInternet Gatewayを選択して、Saveをクリック

f:id:zakihaya:20140503175555p:plain

5) Subnetsを選択 → public subnetのみにチェック → Route Table → Edit の順にクリック

f:id:zakihaya:20140503175953p:plain

6) 作成したpublic subnet用Route Tableを選択して、Saveをクリック

f:id:zakihaya:20140503180147p:plain


APサーバとDBサーバの構築はまた次回。。。

AWS入門 IAMでユーザー管理をする

自分は結構前からAWSは使っているのですが、正直EC2でインスタンス作って運用しかしてません。
そこで、いろんなサービスをいじってみることにしました。

まずはIAMから。

IAMとは

IAM を使用すると、AWS のユーザーとグループを作成および管理し、アクセス権を使用して AWS リソースへのアクセスを許可および拒否できます。

引用元
AWS Identity and Access Management (IAM) (AWS クラウドのアクセス制御) | アマゾン ウェブ サービス(AWS 日本語)

組織内にユーザーやグループを作成して、サーバを作成したりなどの権限を設定できるようです。

グループを作成する

1) AWSにログイン → メニューからIAMを選択

f:id:zakihaya:20140503120628p:plain

2) Create a New Group of Users をクリック

f:id:zakihaya:20140503143751p:plain

3) 好きなグループ名を入力して、Continueをクリック

f:id:zakihaya:20140503145744p:plain

4) 設定する権限のSelectをクリック

Policy Generatorをクリックすれば詳細な設定ができそうだったけど、大変そうだったので今回はRead Only Accessを選択。

f:id:zakihaya:20140503150346p:plain

5) Continueをクリック
Policy Documentの部分を編集すれば権限を変えられる。
そのままでもOK。

f:id:zakihaya:20140503150640p:plain

6) グループにユーザーを追加する
Create New Usersタブを選択して新規ユーザー、Add Existing Usersタブを選択して作成済みユーザーを選択する。

f:id:zakihaya:20140503151019p:plain

※ここでユーザーを作成した場合は、あとでUsersからパスワードを設定する

7) 確認画面でContinueをクリックすると、グループとユーザーが作成される

補足

ログインURLを変更する

初期状態では下のようなURLになっている。

https://XXX.signin.aws.amazon.com/console のような感じになっていて、XXXの部分を好きな文字列に変えることができる。

  • IAMメニューを開く
  • 左のDashboard
  • ページ下部の「Create Account Alias」をクリック
  • そこに希望の文字列を入力してYes, Createを クリック

元に戻す場合は「Remove Account Alias」をクリックすればOK

Security Statusの部分について

Root Account MFA

ログイン時にトークンを発行してセキュリティを高めるものだそう。
本当はやったほうがいいのだけど、今回は見送った。

iPhoneアプリを使って仮想 MFA デバイスにする方法もあるみたい
https://aws.amazon.com/jp/iam/details/mfa/

Password Policy
  • パスワードの最小文字数
  • 大文字を最低1回入れる
  • 小文字を最低1回入れる
  • 数字を最低1回入れる
  • 記号を最低1回入れる

などのポリシーを設定することが可能。

OS X Marvericksで最新のXCodeを入れてbundle installするとエラーになる

開発用のMacが来たので、リポジトリからソースを取ってきてbundle installをすると、下のようなエラーが発生する。

Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

    /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby extconf.rb 
creating Makefile

make "DESTDIR="
compiling atomic_reference.c
atomic_reference.c:53:9: warning: implicit declaration of function 'OSAtomicCompareAndSwap64' is invalid in C99 [-Wimplicit-function-declaration]
    if (OSAtomicCompareAndSwap64(expect_value, new_value, &DATA_PTR(self))) {
        ^
1 warning generated.
linking shared-object atomic_reference.bundle
clang: error: unknown argument: '-multiply_definedsuppress' [-Wunused-command-line-argument-hard-error-in-future]
clang: note: this will be a hard error (cannot be downgraded to a warning) in the future
make: *** [atomic_reference.bundle] Error 1


Gem files will remain installed in /Users/zakihaya/Sites/projectname/vendor/bundle/ruby/2.0.0/gems/atomic-1.1.14 for inspection.
Results logged to /Users/zakihaya/Sites/projectname/vendor/bundle/ruby/2.0.0/gems/atomic-1.1.14/ext/gem_make.out
An error occurred while installing atomic (1.1.14), and Bundler cannot continue.
Make sure that `gem install atomic -v '1.1.14'` succeeds before bundling.

調べていたら、同じような状況に困っている人を発見。

ruby - Can't install mysql gem on OS X - Stack Overflow

これを参考に、

ARCHFLAGS=-Wno-error=unused-command-line-argument-hard-error-in-future bundle install

でうまくいった。

Rails4でsessionの格納先をactive_record_storeにする

Rails4でsessionの格納にActiveRecordを使うやり方。


gemを追加

# Gemfile
gem 'activerecord-session_store', github: 'rails/activerecord-session_store'

gemをインストール

$ bundle install

セッションを格納するテーブルをcreateするmigrationを作成

$ rails generate active_record:session_migration

session_storeを設定する

# config/initializers/session_store.rb
Foo::Application.config.session_store :active_record_store

サーバを再起動すると反映される。


使用したgemはこちら
https://github.com/rails/activerecord-session_store