LoginSignup
59
61

More than 5 years have passed since last update.

ActiveRecordの様々なメソッドたち

Last updated at Posted at 2014-10-31

ActieRecordには様々なメソッドがあります。中にはあまり使わないものもあると思います。以下に個人的な覚え書きの意味もこめて、幾つかのメソッドの使い方や発行されるSQLを載せます。

uniq

SQLのdistinctに相当します。

pry(main)> User.where(name: 'test').uniq
  User Load (0.1ms)  SELECT DISTINCT "users".* FROM "users"  WHERE "users"."name" = 'test'

merge

ActiveRecordでJOINを使ってデータを取得する場合、以下のようにjoinメソッドを使って書く事ができます。

User.joins(:auth_providers).all.where(auth_providers: { provider: 'facebook' })

これは次のようなSQLを発行します。

SELECT "users".* FROM "users" INNER JOIN "auth_providers" ON "auth_providers"."user_id" = "users"."id" WHERE "auth_providers"."provider" = 'facebook'

これと同じことをmergeメソッドを使って書く事ができます。
まずscopeを書きます

class AuthProvider < ActiveRecord::Base
  belongs_to :user

  scope :facebook, -> { where(provider: 'facebook') }
  scope :developer, -> { where(provider: 'developer') }
end

mergeメソッドでは、ここで定義したscopeを使います。上で上げたjoinと同じSQLを発行するには次のように書きます。

 User.joins(:auth_providers).all.merge(AuthProvider.facebook)

where(auth_providers: { provider: 'facebook' })と書いていた箇所がスッキリしますね。
最初mergeっていうメソッド名だったので、違う動きを想像していました。

rewhere

メソッド名から動きを想像出来るでしょうか?百聞は一見に如かずなのでコードを見てみましょう。

pry(main)> User.where(name: 'test')
  User Load (0.1ms)  SELECT "users".* FROM "users"  WHERE "users"."name" = 'test'

rewhereを使うと

pry(main)> User.where(name: 'test').rewhere(name: 'hoge')
  User Load (0.2ms)  SELECT "users".* FROM "users"  WHERE "users"."name" = 'hoge'

分かりますでしょうか?where(name: 'test')が上書きされます。
例えばdefault_scopeとかで指定されている条件を変更したい時などに使うのでしょかね。

reorder

これも名前から想像できるでしょうかね?発行されるSQLを載せます

pry(main)> User.all
  User Load (0.1ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC

default_scopeでorder(id: :desc)を指定ししている場合にreorderを使ってやると

pry(main)> User.all.reorder(id: :asc)
  User Load (0.1ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC

ORDER BYのところが書き変わっていますね。

reverse_order

習得したデータを並び替えます。

pry(main)> User.all.order('name')
  User Load (0.4ms)  SELECT "users".* FROM "users"   ORDER BY name
=> [#<User id: 1, name: "naka", email: "naka5313@gmail.com", provider: "developer", nickname: nil, access_token: nil, secret_token: nil, created_at: "2014-11-26 15:36:12", updated_at: "2014-11-26 15:36:12", image_url: nil, uid: "naka5313@gmail.com">]

reverse_orderを使うと・・。

pry(main)> User.all.order('name').reverse_order
  User Load (3.9ms)  SELECT "users".* FROM "users"   ORDER BY name DESC
=> [#<User id: 1, name: "naka", email: "naka5313@gmail.com", provider: "developer", nickname: nil, access_token: nil, secret_token: nil, created_at: "2014-11-26 15:36:12", updated_at: "2014-11-26 15:36:12", image_url: nil, uid: "naka5313@gmail.com">]

take

一件だけデータを取得します。

[6] pry(main)> User.take
  User Load (0.5ms)  SELECT  "users".* FROM "users"  LIMIT 1
=> #<User id: 1, name: "naka", email: "naka5313@gmail.com", provider: "developer", nickname: nil, access_token: nil, secret_token: nil, created_at: "2014-11-26 15:36:12", updated_at: "2014-11-26 15:36:12", image_url: nil, uid: "naka5313@gmail.com">

以上です。また何かあれば追記します。

59
61
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
59
61