Railsを使ったMongoあれこれ。CRUDの基本操作で使い方を学ぼう！

#はじめに
Railsを使った「Mongo」の基本的な操作方法を
モデルの作成から、「insert、read、update、delete方法」をご紹介します。
また「配列とhashの入れ子」等の「Mongoならでは」なとこも一緒に紹介します。

#モデルの作成
ここでは例として「User」モデルを作成します。

###使用可能な型
``Array, BigDecimal, Boolean, Date, DateTime, Float, Integer, String, Symbol, Time``

###ポイントは2つ
・型を明記しない場合``String``になること
・末尾に ``--timestamps``を追加すること

###下記コマンドでモデルの生成

```
$ rails g scaffold user name age:integer area:array --timestamps
```

すると以下のようなモデルが生成されると思います。

```rb:app/models/user.rb
class User
  include Mongoid::Document
  include Mongoid::Timestamps

  field :name, type: String
  filed :age, type: Integer
  field :area, type: Array
end
```
これで準備は整いました。次は簡単な操作方法を説明します。

#insert文
```rb
def insert
  # 略...
  user = User.new
  user.name = "田中太郎"
  user.age = 21
  user.area = []
  user.area << {:city => "tokyo", :block => "nerima", :lived_in => "2015-03-01"}
  user.save
  # 略...
end


```
こんな感じです。これで「rails c」を起動して下記コマンドを叩いてみてください。

```bash
pry(main)> User.first
```


すると以下のようにinsesrtされていると思います。


```
<User _id: 0000000000000000, created_at: 2015-03-01 00:00:00 UTC, updated_at: 2015-03-01 00:00:00 UTC, name: "田中太郎", age: 21, area: [{"city"=>"tokyo", "block"=>"nerima", "lived_in"=>"2015-03-01"}]>
```
これでinsertは出来るようになりました。次はinsertしたcollectionを操作してみましょう。

#read文
ここではよく使うメソッドを紹介します。基本的に「Active Record」と操作感は変わらないので、それほど違和感はないかと思われます。

###全件取得
```rb:
user = User.all
```
###基本的なwhere句
```rb
user = User.where(:name => "田中太郎")
```

###はじめにヒットした項目を取得
```rb:
user = User.first
```
###最後にヒットした項目を取得
```rb:
user = User.last
```
等です。もちろんまだまだ沢山あるので探してみてください。

##ここでポイント
上記で大体の操作は出来ますが、「ネストされてるものの取得」ここがポイントです。
ココらへんはMongoならではですね！

```rb:
user = User.where('area.lived_in' => "2015-03-01")
```
です。'filed.key' => valueで取得できます。


#update文
次に、先ほどinsertしたcollectionをupdateしてみましょう
ここでは「年齢」と「住所」をupdateします。

##上書き更新の場合
```rb
def update
  # 略...
  user = User.where(:name => "田中太郎").first
  user.age = 22

  # 変更したい配列の要素番号を取得
  array_position = user.use_apps.index {|a| a.select{|k,v| v == "2015-03-01"} != {} }

  user.use_apps[array_position] = {:city => "okinawa", :block => "naha", :lived_in => "2016-04-01"}
  user.save
  # 略...
end
```
です。これを「rails c」で下記コマンドを打って確認すると

```bash
pry(main)> User.first
```
このようにupdateされています。
```
<User _id: 0000000000000000, created_at: 2015-03-01 00:00:00 UTC, updated_at: 2015-03-02 00:00:00 UTC, name: "田中太郎", age: 22, area: [{"city"=>"okinawa", "block"=>"naha", "lived_in"=>"2016-04-01"}]>
```

##配列(area)に対して要素を追加したい場合

```rb
def update
  # 略...
  user = User.where(:name => "田中太郎").first
  user.age = 22
  user.use_apps << {:city => "okinawa", :block => "naha", :lived_in => "2016-04-01"}
  user.save
  # 略...
end
```
です。これを「rails c」で下記コマンドを打って確認すると

```bash
pry(main)> User.first
```
このようにupdateされています。
```
<User _id: 0000000000000000, created_at: 2015-03-01 00:00:00 UTC, updated_at: 2015-03-02 00:00:00 UTC, name: "田中太郎", age: 22, area: [{"city"=>"tokyo", "block"=>"nerima","lived_in"=>"2015-03-01"}, {"city"=>"okinawa", "block"=>"naha", "lived_in"=>"2015-04-01"}]>
```
過去の住所変更履歴を保存しておきたい際などは、
このように追加していく形が良いですね！

##ここでポイント
配列、ハッシュの入れ子から値を検索する場合、
ハッシュでユニークな要素を持っている必要があります。(今回はlived_in)
こんな感じでやってます。

```rb
user = User.first
user_area= user.area

#ヒットした日付のハッシュを取り出す
area = user_area.select {|a| a.select{|k,v| v == "2015-03-01"} != {} }.first
```
以下のようにハッシュで抽出出来ます。

```rb
{"name"=>"田中太郎", "age"=>22, "lived_in"=>"2015-03-01"}
```
(ここはもっと良いやり方がありそう…！)

#delete文
最後にdelete文です。

```rb
def delete
  # 略...
  user = User.where(:name => "田中太郎").first
  user.delete
  user.save
  # 略...
end
```

以上です。特に難しいところはないかなと思います。

#おまけ
String => BSON型の変換

```rb
 bson_id = BSON::ObjectId.from_string(123456789123456789)
```

#最後に
以上が「railsを使ったMongoの操作方法」です。
ここが基本になるので押さえたいですね！

まだまだActive Recordに比べて文献は少ない…
「こんな方法あるで！」とか「こっちのほうがええで！！」等あれば是非！
どんどん情報交換していきましょう！