よく使えるRuby/Rails文法と実行されるSQL文を一緒に学ぶ

  • 8
    いいね
  • 0
    コメント

pluck:任意のカラムの配列を取得

pluckって日本語でなんだ?と思って、ググったら出てきました。
摘むことができるらしい。

スクリーンショット 2016-11-23 18.05.13.png

かんたんな例1

usersテーブルからidとfirst_nameのカラムのみ取得する

User.pluck(:id, :first_name)

実行されるSQL文

SELECT users.id, users.first_name FROM users

limitつけるなら、pluckの前

User.limit(5).pluck(:id, :first_name)
SELECT users.id, users.first_name FROM users LIMIT 5

consoleでの実行結果

[[1, "トム"], [2, "マリ"], [3, "キミ"], [4, "ナミ"], [5, "リサ"]]

かんたんな例2

whereで条件付きで、usersテーブルからidとfirst_nameのカラムのみ取得する。

User.where(sex: "女性").limit(5).pluck(:id, :first_name)

consoleでの実行結果

[[2, "マリ"], [3, "キミ"], [4, "ナミ"], [5, "リサ"], [6, "ミネ"]]

リファレンス
- http://railsdoc.com/references/pluck

map:各要素を{ }内の式を実行した結果を返す

collectと同義。

array = [1,2,3]
array.map(&:to_s)
# => ["1", "2", "3"]
# すべて3倍にして返す
[1, 2, 3].map { |n| n * 3 }
# => [3, 6, 9]

select:{ }内の式がtrueになる要素のみ返す

find_allと同義。

# 2で割り切れるものを抽出する
[1, 2, 3, 4, 5, 6].select { |n| n % 2 == 0 }
# => [2, 4, 6]

# 9で割り切れるものがないので空の配列が返る
[1, 2, 3, 4, 5, 6].select { |n| n % 9 == 0 }
# => []

reject:selectの反対(falseになる要素のみ返す)

falseになる要素がない場合は空の配列が返る。

# 2で割り切れるものじゃないものを抽出する
[1, 2, 3, 4, 5, 6].reject { |n| n % 2 == 0 }
# => [1, 3, 5]

# すべて1で割り切れるので空の配列が返る
[1, 2, 3, 4, 5, 6].reject { |n| n % 1 == 0 }
# => []

find / detect:{ }内 の式がtrueになった最初の要素を返す

ポイント: 最初の要素!!
detect と find は同義。

trueになる要素がない場合はnilが返る。

# 最初の3の倍数を探す
[1, 5, 8, 2, 6, 3].find { |n| n % 3 == 0 }
# => 6

# 7で割り切れるものがないのでnilが返る
[1, 5, 8, 2, 6, 3].find { |n| n % 7 == 0 }
# => nil

find_index:要素の位置を知りたい場合

# 最初の3の倍数の位置を探す
[1, 5, 8, 2, 6, 3].find_index { |n| n % 3 == 0 }
# => 4

grep:引数にマッチする要素のみ返す

引数には正規表現が使える。
マッチする要素がない場合は空の配列が返る。

# 数字を含むものを抽出する
['a1', 'bb', 'c2', 'dd', '5e'].grep(/[0-9]/)
# => ["a1", "c2", "5e"]

# 大文字の英語を含むものがないので空の配列が返る
['a1', 'bb', 'c2', 'dd', '5e'].grep(/[A-Z]/)
=> []

その他文法

joins

テーブルを結合する。

messagesテーブルのuser_idとusersテーブルのidが同じなので、
messagesテーブルのuser_idにusersテーブルのidを紐づけて、
messagesのuser_idにuserテーブルの情報を紐づける。イメージ。
where()でmessagesの条件からそれに値するuser情報を取得することができる!

User.joins("join messages on messages.user_id = users.id")
.where("messages.created_at > ?", 1.month.ago).limit(3)
Post.where(user_id: User.joins("join posts on  posts.user_id = users.id").student.select(:id))

order("RANDOM()")

RANDOM()関数を用いたorder

scope

よくは分かってないが、とりあえず、便利そう。
scopeで遠いところからpostを取ってこれる感じ。

http://qiita.com/okamos/items/724a4a162dfa9e27754a
http://ruby-rails.hatenadiary.com/entry/20140814/1407994568

参考

http://www.programming-magic.com/20080110002650/