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

More than 3 years have passed since last update.


はじめに

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

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


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文

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」を起動して下記コマンドを叩いてみてください。

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」と操作感は変わらないので、それほど違和感はないかと思われます。


全件取得

user = User.all


基本的なwhere句

user = User.where(:name => "田中太郎")


はじめにヒットした項目を取得

user = User.first


最後にヒットした項目を取得

user = User.last

等です。もちろんまだまだ沢山あるので探してみてください。


ここでポイント

上記で大体の操作は出来ますが、「ネストされてるものの取得」ここがポイントです。

ココらへんはMongoならではですね!

user = User.where('area.lived_in' => "2015-03-01")

です。'filed.key' => valueで取得できます。


update文

次に、先ほどinsertしたcollectionをupdateしてみましょう

ここでは「年齢」と「住所」をupdateします。


上書き更新の場合

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」で下記コマンドを打って確認すると

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)に対して要素を追加したい場合

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」で下記コマンドを打って確認すると

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)

こんな感じでやってます。

user = User.first

user_area= user.area

#ヒットした日付のハッシュを取り出す
area = user_area.select {|a| a.select{|k,v| v == "2015-03-01"} != {} }.first

以下のようにハッシュで抽出出来ます。

{"name"=>"田中太郎", "age"=>22, "lived_in"=>"2015-03-01"}

(ここはもっと良いやり方がありそう…!)


delete文

最後にdelete文です。

def delete

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

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


おまけ

String => BSON型の変換

 bson_id = BSON::ObjectId.from_string(123456789123456789)


最後に

以上が「railsを使ったMongoの操作方法」です。

ここが基本になるので押さえたいですね!

まだまだActive Recordに比べて文献は少ない…

「こんな方法あるで!」とか「こっちのほうがええで!!」等あれば是非!

どんどん情報交換していきましょう!